중첩 라우팅
Outlet 컴포넌트로 중첩된 Route 설정하기
앞선 예제에서 메뉴에 포함된 링크를 클릭하게 되면 Menu 컴포넌트는 사라지고 링크된 페이지만이 화면에 렌더링됩니다. 그런데 화면에서 메뉴가 사라지게 되면 사용자는 이전 페이지나 다른 페이지로 이동할 수 없어지기 때문에 일반적으로 메뉴는 화면에 계속 표시되어 있어야 합니다.
따라서 App 컴포넌트의 코드를 아래와 같이 수정합니다.
중첩된 Outlet 컴포넌트
// ... <Routes> <Route path="/" element={<Menu />}> <Route path="" element={<Home />} /> <Route path="about" element={<About />} /> <Route path="news" element={<News />} /> </Route> </Routes> // ...
위의 코드처럼 Route 컴포넌트들을 서로 중첩시킴으로써 상위의 Route 컴포넌트는 항상 화면에 렌더링될 수 있도록 설정할 수 있습니다. 하지만 이렇게 코드를 변경하면 하위의 Route 컴포넌트들이 화면에 렌더링되지 않습니다.
이때 중첩된 하위 레벨의 Route들을 함께 렌더링하기 위해서는 부모 레벨의 Route 내부에 Outlet 컴포넌트를 추가해 주면 됩니다.
Outlet 컴포넌트는 중첩된 Route 컴포넌트 중에서 하위 레벨의 Route 컴포넌트가 렌더링될 때 중첩된 UI를 표시할 수 있게 해 줍니다. 상위 레벨의 Route가 정확히 일치하면 하위 레벨의 Index Route를 렌더링하거나, Index Route가 존재하지 않으면 아무것도 렌더링하지 않습니다.
Index Route 문법
<Route index element={<Home />} />
Index Route는 부모 Route에 여러 자식 Route가 있는 경우 부모 경로에 ‘/’를 추가한 주소와 연결됩니다.
예시(Menu.js)
import { Link, Outlet } from "react-router-dom";
const Menu = () => {
return (
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/news">News</Link>
</li>
</ul>
</nav>
<hr />
<Outlet />
</div>
);
};
export default Menu;
이제 메뉴를 클릭해도 메뉴가 사라지지 않고 정상적으로 화면에 하위 페이지도 함께 표시되는 것을 확인할 수 있습니다.
존재하지 않는 경로 처리하기
이번에는 사용자가 존재하지 않는 경로에 접근했을 경우에 대해 알아보도록 하겠습니다.
위의 예제가 실행 중인 웹 브라우저의 주소창에서 URL 주소 마지막에 ‘/board’라는 경로를 추가해 봅시다. 현재 프로젝트에는 board라는 경로가 존재하지 않기 때문에 콘솔에는 경고 메시지가 출력됩니다. 하지만 애플리케이션이 종료되거나 별도의 동작을 수행하지는 않습니다.
Shell
No routes matched location "/board"
in Routes (created by App)
in App
이것은 사용자 측면에서는 매우 불친절한 방식이며, 사용자에게 존재하지 않는 페이지에 접근하려 했다는 확실한 메시지를 전달해 주는 것이 좋습니다.
Route 컴포넌트의 path 속성을 아래와 같이 설정하면, 경로가 존재하지 않는 경우에 연결할 컴포넌트를 설정할 수 있습니다.
존재하지 않는 경로와 연결된 Route 컴포넌트
<Route path="*" element={<NoMatch />} />
NoMatch.js
import { Link } from "react-router-dom";
const NoMatch = () => {
return (
<div>
<h2>잘못된 경로로 접근하셨습니다.</h2>
<p>
<Link to="/">Home으로 이동하기</Link>
</p>
</div>
);
};
export default NoMatch;
예제(App.js)
// ... <Routes> <Route path="/" element={<Menu />}> <Route path="" element={<Home />} /> <Route path="about" element={<About />} /> <Route path="news" element={<News />} /> <Route path="*" element={<NoMatch />} /> </Route> </Routes> // ...
위의 예제를 실행하고 주소창에 존재하지 않는 경로를 입력해 보면, 이제는 사용자에게 ‘잘못된 경로로 접근했다’는 메시지를 화면을 통해 친절히 알려줄 수 있습니다.