지난 포스팅에서는 react-router의 설치와 구성에 대하여 알아보았다.
이번 포스팅에서는 중첩 라우팅에 대하여 알아보려고 한다.
쉽게 말하면 서브 페이지라고 할 수 있다.
예를 들어서, 지난 포스팅에서 만든 Tech 페이지에서 어떤 카테고리를 클릭하면 해당 페이지를 보여주고 싶을 때 중첩 라우팅을 사용할 수 있다.
지난 포스팅과 동일하게 <Route> 태그 안에 <Route>를 추가하고 path와 element를 입력해준다.
import { BrowserRouter, Routes, Route } from "react-router-dom";
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<MainPage />} />
<Route path="/tech" element={<TechPage />}>
<Route path="/javascript" element={<JavascriptPage />} /> // 추가
<Route path="/react" element={<ReactPage />} /> // 추가
</Route>
<Route path="/blog" element={<BlogPage />} />
</Routes>
</BrowserRouter>
);
}
export default App;
그리고 <JavascriptPage> 컴포넌트에는 아래의 코드를 입력해주었다.
import React from "react";
export default function JavascriptPage() {
return (
<div>
<h2>Javascript Page</h2>
</div>
);
}
아래의 결과 화면을 보자.
tech/javascript 경로로 이동했는데도 불구하고 계속 Tech Page에 머물러 있는 것을 볼 수 있다.
이러한 문제를 해결하기 위해서는, 두 Route에 부모 Route인 Tech Page에서 추가적인 작업이 필요하다.
import React from "react";
import { Outlet } from "react-router-dom";
export default function TechPage() {
return (
<div>
<h1>Tech Page</h1>
<Outlet />
</div>
);
}
<TechPage>
react-router-dom에서 Outlet을 가져오고, Tech Page에 <Outlet /> 컴포넌트를 넣어주면 된다.
Outlet은 부모의 Route element에서 자식의 Route element를 렌더링하기 위해서 사용한다.
정상적으로 JavascriptPage와 ReactPage가 나오는 것을 볼 수 있다.
<ReactPage> 컴포넌트에 코드를 추가하고, 하위에 <ReactDocPage> 컴포넌트도 만들었다.
그리고 App.js 파일을 수정해 주었다.
import React from "react";
import {Link, Outlet} from "react-router-dom";
export default function ReactPage() {
const docs = [
{
id: 1,
title: "React 공부",
date: "05/01/2021",
},
{
id: 2,
title: "React 프로젝트",
date: "31/01/2021",
},
{
id: 3,
title: "useEffect 사용해보기",
date: "10/02/2021",
},
{
id: 4,
title: "React의 Lifecycle이란?",
date: "05/03/2021",
},
{
id: 5,
title: "react-router-dom",
date: "20/03/2021",
},
];
return (
<div>
{docs.map((doc) => (
<Link
to={`${doc.id}`}
key={doc.id}
style={{display: "block", margin: "1rem 0"}}
>
{doc.title}
</Link>
))}
<Outlet />
</div>
);
}
import React from "react";
import {useParams} from "react-router-dom";
export default function ReactDocPage() {
const params = useParams();
return (
<>
<div>현재 ** {params.docId}페이지 입니다!</div>
</>
);
}
import {BrowserRouter, Routes, Route} from "react-router-dom";
import MainPage from "./components/MainPage";
import TechPage from "./components/TechPage";
import BlogPage from "./components/BlogPage";
import JavascriptPage from "./components/JavascriptPage";
import ReactPage from "./components/ReactPage";
import ReactDocPage from "./components/ReactDocPage";
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<MainPage />} />
<Route path="/tech" element={<TechPage />}>
<Route path="javascript" element={<JavascriptPage />} />
<Route path="react" element={<ReactPage />}>
<Route path=":docId" element={<ReactDocPage />} />
</Route>
</Route>
<Route path={"blog/"} element={<BlogPage />} />
</Routes>
</BrowserRouter>
)
}
export default App;
/tech/react 페이지에서 해당 목록을 누르면
return (
<>
<div>현재 ** {params.docId}페이지 입니다!</div>
</>
);
위의 코드 뿐만 아니라 /tech/react 페이지의 리스트까지 보여지게 된다.
App.js 파일에서 ReactDocPage가 ReactPage의 하위에 중첩 됐기 때문에 이와 같은 문제가 발생한다.
이를 해결하기 위해서는 중첩을 시키지 않고 같은 레벨의 위치로 작성해주면 된다.
import {BrowserRouter, Routes, Route} from "react-router-dom";
import MainPage from "./components/MainPage";
import TechPage from "./components/TechPage";
import BlogPage from "./components/BlogPage";
import JavascriptPage from "./components/JavascriptPage";
import ReactPage from "./components/ReactPage";
import ReactDocPage from "./components/ReactDocPage";
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<MainPage />} />
<Route path="/tech" element={<TechPage />}>
<Route path="javascript" element={<JavascriptPage />} />
<Route path="react" element={<ReactPage />} />
<Route path=":docId" element={<ReactDocPage />} /> // 수정
</Route>
<Route path={"blog/"} element={<BlogPage />} />
</Routes>
</BrowserRouter>
)
}
export default App;
리스트가 보이지 않는 것을 확인할 수 있다.