6.0.0 이상 버전에서 react-router-dom 사용시 nested routes 작성법에 대해 정리하려 합니다.
그 전에 먼저 React Router에 대한 몇가지 내용을 작성하겠습니다.
React Router - Route
React Router의 Route 컴포넌트는 사용자가 접속한 url을 분석하여
어느 컴포넌트를 보여줄지 정의할 수 있도록 합니다.
예를 들어 "https:// ... /papers"를 보여준다고 하면
<Route path="/papers" element={<Papers />} />
위와 같은 식으로 라우팅을 할 수 있습니다.
Route는 한가지 경로에 대해 정의할 수 있습니다.
따라서 여러 경로에 대해 정의하려면 여러개의 Route가 필요합니다.
따라서 이를 묶어주는 역할을 하는 컴포넌트가 Routes입니다.
React Router - Routes
따라서 아래와 같은 라우팅을 정의할 수 있게됩니다.
<Routes>
<Route path="/" element={<Home />} />
<Route path="/papers" element={<Papers />} />
<Route path="/papers/:id" element={<Paper />} />
<Route path="/user/profile" element={<Profile />} />
<Route path="/user/story" element={<Story />} />
</Routes>
위 라우팅을 해석해보면
1. 최상위 경로에서는 Home 컴포넌트를 렌더링
2. "/papers" 에서는 Papers 컴포넌트를 렌더링
3. "/papers/:id" Papers에서 특정 id를 통해 그에 대응하는 Paper 컴포넌트 렌더링
4. "/user/profile"에서는 Profile 컴포넌트를 렌더링
5. "/user/story"에서는 Story 컴포넌트를 렌더링
이라고 할 수 있습니다.
이때 3번과 같이 특정 id에 맞는 경로라던지 4번과 같은 특정 경로의 하위 경로에 대한 라우팅은
물론 위와 같이 구성할 수도 있지만, /papers에 먼저 들어간 후 특정 id에 대한 라우팅이라던지
/user에 먼저 들어간 후, /user/profile에 들어가도록 하는 경우는
nested routes를 통해 더 직관적으로 라우팅을 구성할 수 있습니다.
nested routes
이때 두가지 구성 방법이 존재합니다.
1. 와일드 카드(*) 를 통한 구성방법
2. Outlet 컴포넌트를 사용한 구성방법
와일드 카드(*) 를 사용한 nested routes
먼저 와일드 카드를 사용한 nested routes 구성 방법입니다.
<Routes>
...
<Route path="/papers/*" element={<Papers />} />
...
</Routes>
위에서 ":id" 라고 작성했던 분을 삭제하고, 와일드 카드(*)로 수정합니다.
이제 id에 대응하여 보여줄 컴포넌트를 Papers 컴포넌트 내부에 Routes를 작성하여 구성할 수 있게됩니다.
function Papers() {
return (
<Container>
...
<Routes>
<Route path=":id" element={<Paper />} />
</Routes>
</Container>
);
}
특징은 전과 같이 루트 경로부터 작성하는 것이 아닌,
그저 새로운 경로만 뒤에 붙여서 Route를 작성하면 된다는 점입니다.
컴포넌트 단위로 라우팅을 구분하여 작성할때, 사용하기 용이하다고 생각하는 방법입니다.
Outlet 컴포넌트를 사용한 구성방법
와일드 카드를 사용한 방법은 컴포넌트 내에서 따로 라우팅을 구성해야 했습니다.
맨 처음 라우팅을 구성하는 단계에서 어디로 라우팅 할지를 정의하고 싶다면
react-router-dom의 Outlet 컴포넌트를 사용할 수 있습니다.
<Routes>
...
<Route path="/papers" element={<Papers />}>
<Route path=":id" element={<Paper />} />
</Route>
...
</Routes>
Outlet을 사용하게 되면 위와같이 한번에 라우팅을 구성할 수 있게됩니다.
따라서 더욱 직관적이라고 할 수 있습니다.
이제 Papers 컴포넌트에 라우팅하여 불러올 컴포넌트가 위치할 부분에 Outlet 컴포넌트를 작성해주어야합니다.
이는 와일드카드 작성 시, Routes를 사용하여 라우팅을 정의한 위치와 동일합니다.
function Papers() {
return (
<Container>
...
{/*
<Routes>
<Route path=":id" element={<Paper />} />
</Routes>
*/}
<Outlet />
</Container>
);
}
react-router-dom에서 Outlet 컴포넌트를 import한 후,
기존에 Routes가 존재했던 위치에 작성해주면 정상적으로 동작합니다.
참고한 글
https://ui.dev/react-router-nested-routes
https://reactrouter.com/docs/en/v6/getting-started/overview#nested-routes