[WizSched] react-router-dom v6 Outlet 적용
🍀 목차
문제
Outlet
적용하기
문제
지금까지 프로젝트에서 Header
가 고정된 레이아웃을 만들 때 app.tsx
에서 Header
를 선언하여 사용했었다. 이 구조를 다시 보니 라우팅을 관리하는 컨테이너와 UI 컴포넌트가 뒤섞여 있어 읽기 어렵다고 생각했다. 또한 프로젝트에 여러 API를 활용하기에 페이지마다 Header
가 달라질 수 있다 판단했다. 그럴때마다 pathname을 이용해 조건문을 작성하여 렌더링 여부를 판단하기는 번거롭다고 느꼈다.
이를 어떻게 개선할 수 있을까 검색해 보다가 react-router-dom(v6)의 Outlet을 알게 되었다.
Outlet
Outlet은 중첩 라우트 구조에서 자식 라우트를 표시하는 데 사용된다. 부모 라우트의 특정 위치에서 자식 라우트를 렌더링 할 수 있도록 도와준다. 일반적으로 특정 컴포넌트 내의 다른 하위 컴포넌트의 자리를 지정하는 데 활용된다.
중첩 라우트 구조
하나의 라우트 안에 또 다른 라우트를 중첩하여 사용하는 것.
페이지의 일부를 독립적으로 관리할 수 있어 재사용성을 향상시킬 수 있다. 중첩 라우트 구조에서 부모 라우트는 특정 경로에 대한 레이아웃 및 공통 컴포넌트가 들어가고, 그 안에 자식 라우트들이 중첩된다. 각 자식 라우트는 부모 라우트 경로에 추가되어 특정 컴포넌트를 렌더링 한다.
<Routes> <Route path="/" element={<Dashboard />}> <Route path="messages" element={<DashboardMessages />} /> <Route path="tasks" element={<DashboardTasks />} /> </Route> </Routes> //https://reactrouter.com/en/main/components/outlet
위 코드에서 경로/
는DashBoard
컴포넌트가, 경로/messages
는DashboardMessages
컴포넌트로 중첩되어 렌더링, 경로/tasks
는DashboardTasks
컴포넌트로 중첩되어 렌더링 된다.
function Dashboard() {
return (
<div>
<h1>Dashboard</h1>
{/* This element will render either <DashboardMessages> when the URL is
"/messages", <DashboardTasks> at "/tasks", or null if it is "/"
*/}
<Outlet />
</div>
);
}
function App() {
return (
<Routes>
<Route path="/" element={<Dashboard />}>
<Route
path="messages"
element={<DashboardMessages />}
/>
<Route path="tasks" element={<DashboardTasks />} />
</Route>
</Routes>
);
}
해당 코드로 확인해보면 루트 경로의 결과는 아래와 같이 나온다.
경로 /messages
는 아래와 같이,
경로 /tasks
는 아래와 같다.
const Layout = () => {
return (
<>
<Header />
<Outlet />
<Footer />
</>
);
};
export default Layout;
이를 활용하여 다양한 Layout을 만들어 관리할 수 있다.
적용하기
createBrowserRouter를 이용해 router설정을 해준다. (참고 문서)
//router.tsx
const router = createBrowserRouter([
{
path: ROUTE_PATH.ROOT, // '/'
element: <Layout />,
children: [
{
path: ROUTE_PATH.LOGIN, // 'login'
element: <LoginPage />,
},
],
},
]);
export default router;
//index.tsx에 RouterProvider 추가
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>,
);
path ROOT의 children으로 들어간 element들은 모두 Layout
을 거치게 된다.
Layout
은 위에 Header가 포함된 구조이다.
Header에 포함된 로그인 버튼을 클릭하면 /login
으로 간다.
LoginPage
에는 Header가 포함되어 있지 않다.
이제 다양한 레이아웃을 커스텀하기 편해졌다. ✨