동적 라우팅 - Path parameter
React에는 자체적인 라우팅 기능이 없다.
그래서 react-router-dom의 BrowserRouter와 Route 컴포넌트를 이용한다.
그 외 부가 기능으로 Path, Query parameter도 사용할 수 있다.
지금까지 해온 라우팅 방법으로는 완전히 정해진 경우에 대해서만 경로를 표현할 수 있었다.
"/" => <App />
"/users" => <Users />
"/products" => <Products />
-
위의 url을 살표보면 마지막에 특정 id값이 들어가고 그 값에따라
서로 다른 상세 페이지 정보가 화면에 그려진다.
id값에 따라 무수히 많은 url이 나타날 것이고, 점점 많아진다면
모든 url에 대해 미리 경로의 형태와 갯수를 결정할 수 없게 된다. -
즉, URL에 들어갈 id를 변수처럼 다뤄야 할 필요성이 있다.
-
이처럼 동적일 수 있는 경로에 대하여 라우팅 하는 것을 동적 라우팅 이라고 부른다.
-
라우트 경로에 특정 값을 넣어 해당하는 페이지로 이동할 수 있게 하는것을
동적 라우팅
이라고 한다. -
Path Parameter, Query Parameter를 사용한다.
-
주로 상품 목록 페이지에서 상품 상세 페이지로 이동할 때 활용되는 기능이다.
특정 resource를 식별하고 싶을때 Path Param,
정렬이나 필터링을 해야할때 Query Param 을 쓴다고 한다.
Path Parameter
localhost:3000/product/2
localhost:3000/product/45
localhost:3000/product/125
localhost:3000/product/2
localhost:3000/product/45
localhost:3000/product/125
2, 45, 125와 같이 라우트 경로 끝에 들어가는 각기 다른 id 값들을 저장하는 매개변수를 Path Parameter 라고 한다.
Path Parameter 는 Routes 컴포넌트에서 다음과 같이 정의된다.
<Router>
<Switch>
<Route exact path='/product/:id' component={productDetail} />
</Switch>
</Router>
: 는 Path Parameter가 올 것임을 의미한다.
id는 해당 Path Parameter의 이름을 의미 한다. 변수 명을 짓듯, 임의의 이름을 지정할 수 있다.
history, match, location 객체
React Router 에서 제공하는 history
, match
, location
객체를 사용하여 위의 id 값을 가져올 수 있다.
**Routes.js
의 Route
컴포넌트의 component
프로퍼티에 직접 연결되어 있는 하위 컴포넌트**는 history
, location
, match
3가지 객체를 props
를 통해 제공 받는다.
자식 컴포넌트에서 콘솔찍어보면,
const {history, location, match} = this.props;
console.log(history);
console.log(history);
console.log(history);
history
객체는 페이지 이동을 위한 여러 메서드들을 담고있다. (ex,push
)location
객체는 현재 url 경로에 관한 정보를 담고있다.match
객체는 Path Parameter 에 관한 정보를 담고있다..
우리가 페이지 이동을 위해 사용하던 push 함수도 history
객체가 제공하는 기능이다.
(ex. onClick={ () ⇒ this.props.history.push('/main') }
)
But, 직접 Route의 component 프로퍼티에 직접 연결이 되지 않은 자식 컴포넌트에서는 history, location, match 객체를 제공받지 못한다.
withRouter 함수를 이용한다. 인자로 컴포넌트를 받고, 해당 컴포넌트에 3가지 객체를 추가한 컴포넌트를 반환한다.
import { withRouter } from 'react-router-dom';
class 자식컴포넌트 extends React.Component {
render() {
console.log(this.props); // { history: {}, location:{}, match:{}, ... }
return(
...
)
}
}
export default withRouter(자식컴포넌트);
this.props.match.params.id
Path Parameter 로 명시해둔 값은 match 객체에 담긴다.
match 함수를 이용해 id 값을 가져온다.
class ProductDetail extends React.Component {
...
render() {
console.log(this.props.match.params.id) // 1
return (
...
);
}
}
그 id에 해당하는 정보를 fetch 해온다.
componentDidMount() {
fetch(`${API}/${this.props.match.params.id}`)
.then(res => res.json())
.then(res => ...);
정리
-
Card.js
에서 Link나 onClick 을 이용해 경로로 보내준다. (경로 + id로)
(ex. <Link to="/monsters/${this.props.id}">
)
router에 직접 연결되지 않은 요소에서 보내주기때문에 withRouter 연결돼 있어야 함.
-
Route 설정해준다.
<Route exact path="/monsters/:id" component={MonsterDetail} />
-
MonsterDetail.js
(부모)에서 componentDidMount() {
fetch("https://jsonplaceholder.typicode.com/users/" + this.props.match.params.id).then(res => ~생략~state저장.
}
-
데이터를 저장한 state를 다시 card.js로 넘겨준다.
그에 해당하는 카드, 정보가 render된다.
monsterDetail.js
import React, { Component } from "react";
import Card from "./Components/Card/Card";
import "./MonsterDetail.scss";
class MonsterDetail extends Component {
state = {
monster: {},
};
componentDidMount() {
fetch(
`https://jsonplaceholder.typicode.com/users/${this.props.match.params.productId}`
)
.then((res) => res.json())
.then((res) => this.setState({ monster: res }));
}
render() {
const { monster } = this.state;
return monster.name ? (
<div className="url-parameters">
<div className="btn-wrapper">
<button>Back to Monsters List</button>
</div>
<Card
key={monster.id}
id={monster.id}
name={monster.name}
email={monster.email}
/>
<div className="btn-wrapper">
<button>Previous</button>
<button>Next</button>
</div>
</div>
) : null;
}
}
export default MonsterDetail;
Card.js
import React, { Component } from "react";
import { withRouter } from "react-router-dom";
import "./Card.scss";
class Card extends Component {
render() {
return (
<div
className="card-container"
onClick={() =>
this.props.history.push(`/monsters/${this.props.id}`)
}
>
<img
src={`https://robohash.org/${this.props.id}?set=set2&size=180x180`}
alt=""
/>
<h2>{this.props.name}</h2>
<p>{this.props.email}</p>
</div>
);
}
}
export default withRouter(Card);
Route.js
import React, { Component } from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import Pagination from "./Lectures/Pagination/Users";
import UrlParameters from "./Lectures/UrlParameters/Monsters";
import MonsterDetail from "./Lectures/UrlParameters/MonsterDetail";
import StateProps from "./Lectures/StateProps/StateProps";
import OnChange from "./Lectures/OnChange/OnChange";
import MenuTab from "./Lectures/MenuTab/MenuTab";
import Lifecycle from "./Lectures/LifeCycle";
export default class Routes extends Component {
render() {
return (
<Router>
<Switch>
<Route exact path="/StateProps" component={StateProps} />
<Route exact path="/onChange" component={OnChange} />
<Route exact path="/MenuTab" component={MenuTab} />
<Route exact path="/monsters" component={UrlParameters} />
<Route
exact
path="/monsters/:productId"
component={MonsterDetail}
/>
<Route exact path="/Pagination" component={Pagination} />
<Route exact path="/lifecycle" component={Lifecycle} />
</Switch>
</Router>
);
}
}
Author And Source
이 문제에 관하여(동적 라우팅 - Path parameter), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@heyho9292/동적-라우팅-Path-parameter
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Card.js
에서 Link나 onClick 을 이용해 경로로 보내준다. (경로 + id로)
(ex. <Link to="/monsters/${this.props.id}">
)
router에 직접 연결되지 않은 요소에서 보내주기때문에 withRouter 연결돼 있어야 함.
Route 설정해준다.
<Route exact path="/monsters/:id" component={MonsterDetail} />
MonsterDetail.js
(부모)에서 componentDidMount() {
fetch("https://jsonplaceholder.typicode.com/users/" + this.props.match.params.id).then(res => ~생략~state저장.
}
데이터를 저장한 state를 다시 card.js로 넘겨준다.
그에 해당하는 카드, 정보가 render된다.
import React, { Component } from "react";
import Card from "./Components/Card/Card";
import "./MonsterDetail.scss";
class MonsterDetail extends Component {
state = {
monster: {},
};
componentDidMount() {
fetch(
`https://jsonplaceholder.typicode.com/users/${this.props.match.params.productId}`
)
.then((res) => res.json())
.then((res) => this.setState({ monster: res }));
}
render() {
const { monster } = this.state;
return monster.name ? (
<div className="url-parameters">
<div className="btn-wrapper">
<button>Back to Monsters List</button>
</div>
<Card
key={monster.id}
id={monster.id}
name={monster.name}
email={monster.email}
/>
<div className="btn-wrapper">
<button>Previous</button>
<button>Next</button>
</div>
</div>
) : null;
}
}
export default MonsterDetail;
import React, { Component } from "react";
import { withRouter } from "react-router-dom";
import "./Card.scss";
class Card extends Component {
render() {
return (
<div
className="card-container"
onClick={() =>
this.props.history.push(`/monsters/${this.props.id}`)
}
>
<img
src={`https://robohash.org/${this.props.id}?set=set2&size=180x180`}
alt=""
/>
<h2>{this.props.name}</h2>
<p>{this.props.email}</p>
</div>
);
}
}
export default withRouter(Card);
import React, { Component } from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import Pagination from "./Lectures/Pagination/Users";
import UrlParameters from "./Lectures/UrlParameters/Monsters";
import MonsterDetail from "./Lectures/UrlParameters/MonsterDetail";
import StateProps from "./Lectures/StateProps/StateProps";
import OnChange from "./Lectures/OnChange/OnChange";
import MenuTab from "./Lectures/MenuTab/MenuTab";
import Lifecycle from "./Lectures/LifeCycle";
export default class Routes extends Component {
render() {
return (
<Router>
<Switch>
<Route exact path="/StateProps" component={StateProps} />
<Route exact path="/onChange" component={OnChange} />
<Route exact path="/MenuTab" component={MenuTab} />
<Route exact path="/monsters" component={UrlParameters} />
<Route
exact
path="/monsters/:productId"
component={MonsterDetail}
/>
<Route exact path="/Pagination" component={Pagination} />
<Route exact path="/lifecycle" component={Lifecycle} />
</Switch>
</Router>
);
}
}
Author And Source
이 문제에 관하여(동적 라우팅 - Path parameter), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@heyho9292/동적-라우팅-Path-parameter저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)