동적라우팅(Dynamic Routing)
보통 웹사이트는 전체 아이템이 보여지는 리스트 페이지
와 거기서 어떤 아이템을 선택했을 때 해당 아이템의 디테일 한 정보가 보여지는 상세 페이지
로 구성된다.
위 짤을 보면 각각의 카드를 클릭할 때, wanted.co.kr/wd/
끝에 해당 아이템의 id 값이 추가되어 페이지 이동을 한다. 또한 이동한 페이지에서는 id 값에 해당하는 데이터가 보여지는 것을 볼 수 있다.
이처럼 라우트 경로에 특정 값을 넣어 해당하는 페이지로 이동할 수 있게 하는 것을 **동적 라우팅**
이라고 한다.
Path Parameter
localhost:3000/product/2
localhost:3000/product/45
localhost:3000/product/125
2
, 45
, 125
와 같이, 라우트 경로 끝에 들어가는 각기 다른 id값들을 저장하는 매개 변수를 Path Parameter라고 한다.
Path Parameter는 Routes 컴포넌트에서 다음과 같이 정의된다.
<Router>
<Routes>
<Route path='/product/:id' element={<productDetail />} />
</Routes>
</Router>
function ProductDetail() {
const params = useParams();
const productId = params.id;
}
:
는 Path Parameter가 올 것임을 의미한다.id
는 해당 Path Parameter 의 이름을 의미한다. 변수 명을 짓듯이 임의의 이름을 지정해줄 수 있다. ex):productId
Route 컴포넌트에 component 프로퍼티에 :id
를 통해 Path Parameter를 명시해준 후 동적라우팅이 구현되는 흐름을 보면...
/product/1
로 이동한다. URL이 /product/1
로 변하면, Route 컴포넌트에 정의되어 있는 path='/product/:id'
에 따라, ProductDetail 컴포넌트가 마운트 된다.1
인 아이템에 대한 정보를 요청한다.setState
함수를 통해 state에 저장하고, 이를 통해 상세 페이지 UI가 그려진다.2번 순서에서, ProductDetail 컴포넌트의 componentDidMount(=useEffect)에서 백앤드에 id가 1
에 해당하는 정보를 요청하였다. 그런데, 1
은 URL에 담겨있다. (/product/1
). ProductDetail 컴포넌트에서는 이것을 어떻게 가져왔을까?
useNavigate, useParams, useLocation 훅
React Router에서 제공하는 useNavigate
, useParams
, useLocation
훅을 사용하여 위의 id값을 가져올 수 있다. 어떻게 가져오는지에 앞서 설명해보면,
Routes.js
의 Route
컴포넌트의 component
프로퍼티에 직접 연결되어 있는 하위 컴포넌트는 useNavigate
, useLocation
, useParams
3가지 훅을 통해 제공받는다.
// Routes.js
<Route exact path='/product/detail/:id' element={<ProductDetail />} />
// ProductDetail.js
const navigate = useNavigate();
const location = useLocation();
const params = useParams();
<Link to="" />
navigate(`/product/detail/${productId}`);
const productId = params.id;
// { history: {}, location: {}, match: {}, ... }
console.log({ history, location, match })
return (
...
);
ProductDetail 컴포넌트는 Route 컴포넌트를 통해 3가지 훅을 제공받는다.
cf. 우리가 페이지 이동을 위해 사용하던 push함수도 history
객체가 제공하는 기능이다. (ex. onClick={ () => history.push('/main') }
)
useParams().id
그럼 이제 어떻게 url에 담겨있는 id값을 가져올까?
params 객체를 이용해 가져올 수 있는데, Path Parameter로 명시해둔 값은 params 객체에 담기기 때문이다.
// ProductDetail.js
// current url -> localhost:3000/product/1
function ProductDetail() {
const params = useParams();
console.log(params.id) // 1
return (
...
);
}
따라서 useEffect 메서드에서 해당 id값을 통해 서버에 요청을 보내는 것을 통해 원하는 정보를 받아올 수 있다.
useEffect(() => {
fetch(`${API}/${params.id}`)
.then(res => res.json())
.then(res => ...)
, [match]);
정리
동적라우팅의 구현 흐름을 로직을 구현하게 된다.
navigate('/product/1')
로 상세페이지로 이동http://localhost:3000/product/1
과 같이 변경되어 있다.params.id
에서 가져올 수 있다.const params = useParams();
useEffect(() => {
const { id } = params;
fetch(`http://123.456.123.123:8000/products/${id}`) // 1
.then(res => res.json())
.then(res => setState({ data: res }))
}, [match]);
res
)를 컴포넌트의 state 객체에 저장해 준다.