[React] 동적라우팅(Dynamic Routing)

짱쫑·2022년 1월 16일
4

Routing

목록 보기
2/3
post-thumbnail

동적라우팅(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를 명시해준 후 동적라우팅이 구현되는 흐름을 보면...

  1. 카드를 클릭하면, onClick 이벤트시 발생하는 push 함수를 통해 /product/1로 이동한다. URL이 /product/1로 변하면, Route 컴포넌트에 정의되어 있는 path='/product/:id' 에 따라, ProductDetail 컴포넌트가 마운트 된다.
  2. ProductDetail컴포넌트에서는 백엔드에 id가 1인 아이템에 대한 정보를 요청한다.
  3. 응답으로 받은 정보를 setState함수를 통해 state에 저장하고, 이를 통해 상세 페이지 UI가 그려진다.

2번 순서에서, ProductDetail 컴포넌트의 componentDidMount(=useEffect)에서 백앤드에 id가 1에 해당하는 정보를 요청하였다. 그런데, 1은 URL에 담겨있다. (/product/1). ProductDetail 컴포넌트에서는 이것을 어떻게 가져왔을까?

useNavigate, useParams, useLocation 훅

React Router에서 제공하는 useNavigate, useParams, useLocation 훅을 사용하여 위의 id값을 가져올 수 있다. 어떻게 가져오는지에 앞서 설명해보면,

Routes.jsRoute컴포넌트의 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가지 훅을 제공받는다.

  • useNavigate는 페이지 이동을 위한 여러 메서드이다. (ex. history.push)
  • useLocation는 현재 url 경로에 관한 정보를 담는다.
  • useParams는 Path Parameter에 관한 정보를 담는다.

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')로 상세페이지로 이동
  • 상세 페이지로 이동하면 url은 http://localhost:3000/product/1과 같이 변경되어 있다.
  • 페이지에 필요한 데이터를 Backend에서 fetching한다.
    - 필요한 id는 url에 존재하므로 params.id에서 가져올 수 있다.
    • 해당 id를 가지고 백앤드에서 만들어준 API를 호출한다.
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 객체에 저장해 준다.
  • state객체에 담긴 데이터로 컴포넌트 UI를 랜더해준다.
profile
不怕慢, 只怕站

0개의 댓글