TIL archiving ···.ᐟ/React

중첩 라우팅 & Outlet

dayoung-archive 2024. 10. 8. 19:00

📌 중첩 라우팅 (Nested Routing)

  • 중첩 라우팅은 리액트 같은 SPA(Single Page Application)에서 여러 페이지 또는 뷰를 구성할 때 사용.
  • 복잡한 UI 구조를 효과적으로 관리할 수 있게 해주고, URL 구조에 맞게 컴포넌트를 계층적으로 배치할 수 있게 해준다.
  • 공통된 레이아웃이나 기능을 가진 여러 페이지를 쉽게 구성할 수 있다. (코드의 재사용성 증가)

 

사실 이렇게 설명으로만 들으면 사실 이해하기 어렵고 와닿지 않는다.

중첩 라우팅을 하는 이유와 필요성을 쉽게 알기 위해 예제를 통해  중첩 라우팅 하지 않은 경우를 먼저 살펴보자!

 

 

 

 

만약 메뉴바를 만들고 각 메뉴를 클릭 했을 때, 메뉴바는 고정되어 있고 클릭 한 페이지의 내용만 보여주고 싶다면?

// Menu.tsx

import { Link } 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 />
    </div>
  );
};

export default Menu;

먼저 Menu 안에 Home, About, News 각 페이지가 포함 되어 있는 구조를 만들어 준다.

(링크를 클릭하면 해당 페이지로 이동할 수 있도록) 

 

// App.tsx

import { Routes, Route } from "react-router-dom";
import Home from "./components/Home";
import About from "./components/About";
import News from "./components/News";
import Menu from "./Menu";

const App = () => {
  return (
    <div>
      <h1>React Router</h1>
      <Routes>
        <Route path="/menu" element={<Menu />} />
        <Route path="" element={<Home />} />
        <Route path="about" element={<About />} />
        <Route path="news" element={<News />} />
      </Routes>
    </div>
  );
};

export default App;

그리고 Route 컴포넌트를 사용해 경로를 설정해준 뒤, 실행시켜보면...

 

메뉴 안에 있는 링크(Home / About/ News)를 클릭했을 때

메뉴는 사라지고 링크된 페이지만 화면에 렌더링 되는 걸 확인할 수 있다. URL도 계속 변함..

?????????

 

아니 나는 메뉴를 고정해서 페이지 이동할 수 있게 하고 싶다고!!!!! 이건 내가 원한 게 아님.. ㅠ

 

 

 

바로 이런 경우에 중첩 라우팅이 필요하다!

상위 경로인 메뉴가 화면에 계속 보일 수 있도록, 말 그대로 menu 뒤에 하위 경로를 붙여주는 것

 


 

// App.tsx

import { Routes, Route } from "react-router-dom";
import Home from "./components/Home";
import About from "./components/About";
import News from "./components/News";
import Menu from "./Menu";

const App = () => {
  return (
    <div>
      <h1>React Router</h1>
      <Routes>
        <Route path="/menu" element={<Menu />}>
          <Route index element={<Home />} />  
          <Route path="about" element={<About />} />
          <Route path="news" element={<News />} />
        </Route>
      </Routes>
    </div>
  );
};

export default App;

위처럼 상위 라우트인 Menu에다 하위 라우트를 중첩시킨 형태로 루트 컴포넌트를 수정해 준다.

 

 

 

 

오.. 진짜 라우트 중첩만 해주면 끝?????

 

 

여기서 Outlet이라는 컴포넌트를 사용해줘야 route를 렌더링 시켜 화면에 보일 수 있다.

그렇다면 Outlet은 뭘까?

 

 

📌 Outlet

  • React Router v6에서 새롭게 도입된 컴포넌트로, 내 하위 라우트를 위치 시킬  때 사용
  • 상위 라우트에 Outlet 컴포넌트를 사용하면, 각 경로에 맞는 컴포넌트가 Outlet 위치에 렌더링 되도록 해준다.

 

 

이걸 계속해서 코드로 이어서 확인 해보면

// Menu.tsx

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;

 

 

이렇게 상위 라우트에 Outlet 컴포넌트를 추가해, 위에서 중첩한 라우트가 렌더링 될 위치를 지정해준다.

(⭐ 즉, 여기서 <Outlet /> 위치에 <Home />, <About />, <News /> 가 렌더링 되는 것)

 

 

 

여기까지 해주고 실행 해보면,,,

 

이렇게 URL에 따라 컴포넌트를 렌더링 할 수 있고, 메뉴가 화면에 계속 떠 있는 것을 확인 할 수 있다!

 

+ 아무것도 클릭하지 않았을 때 기본으로 Home의 페이지가 보이는데, 이는 Home을 index route로 설정했기 때문이다.
(➰App.tsx 코드 참고)

이렇게 하면 하위 라우트 중 기본으로 보여지는 라우트를 선택할 수 있기 때문에 사용자가 아무것도 클릭하지 않았을 때,
기본으로 보여질 페이지를 채울 수 있다.

 

 

 

 

리액트 라우터 공식문서 (route index, outlet 참고)

https://reactrouter.com/en/main/route/route

https://reactrouter.com/en/main/components/outlet

 

https://react.vlpt.us/react-router/01-concepts.html