React Router 6 완벽 가이드: 핵심 컴포넌트와 Hooks 사용법

1. 개요

React Router 6는 npm에 세 가지 패키지로 배포됩니다:

  • react-router: 라우팅의 핵심 라이브러리로, 다양한 컴포넌트와 Hooks 제공
  • react-router-dom: react-router의 모든 기능에 <BrowserRouter> 등 DOM 전용 컴포넌트 추가
  • react-router-native: react-router의 모든 기능에 <NativeRouter> 등 React Native API 추가

5.x 버전과의 주요 차이점:

  • 내장 컴포넌트 변경: <Switch> 제거, <Routes> 도입
  • 문법 변경: component={About}element={<About/>}
  • 새로운 Hooks: useParams, useNavigate, useMatch
  • 함수형 컴포넌트 공식 권장

2. 컴포넌트

2.1 <BrowserRouter>

애플리케이션 전체를 감싸는 라우터 컨테이너입니다.

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";

ReactDOM.render(
  <BrowserRouter>
    {/* 전체 앱 구조 (보통 App 컴포넌트) */}
  </BrowserRouter>,
  document.getElementById("root")
);

2.2 <HashRouter>

<BrowserRouter>와 동일한 역할을 수행하지만, URL의 해시(hash)를 사용합니다. 5.x와 사용법이 동일합니다.

2.3 <Routes>와 <Route>

6.x에서는 <Switch>가 제거되고 <Routes>로 대체되었습니다. <Routes><Route>를 감싸야 하며, <Route>는 현재 URL과 경로(path)가 일치할 때 해당 element를 렌더링합니다.

  • caseSensitive 속성: 대소문자 구분 여부 (기본값 false)
  • 중첩 라우팅 지원: useRoutes()<Outlet>을 함께 사용
<Routes>
  <Route path="/login" element={<Login />} />
  <Route path="home" element={<Home />}>
    <Route path="test1" element={<Test />} />
    <Route path="test2" element={<Test2 />} />
  </Route>
  <Route path="users">
    <Route path="xxx" element={<Demo />} />
  </Route>
</Routes>

2.4 <Link>

URL을 변경하지만 네트워크 요청을 보내지 않는 라우팅 링크입니다. <BrowserRouter> 또는 <HashRouter> 내부에서 사용해야 합니다.

import { Link } from "react-router-dom";

function Test() {
  return (
    <div>
      <Link to="/경로">버튼</Link>
    </div>
  );
}

2.5 <NavLink>

<Link>와 유사하지만, 현재 경로와 일치할 때 자동으로 "활성(active)" 스타일을 적용합니다. className에 함수를 전달하여 커스텀 스타일링이 가능합니다.

// 클래스명 커스텀
<NavLink
  to="login"
  className={({ isActive }) => isActive ? "base one" : "base"}
>
  login
</NavLink>

// end 속성: 하위 경로가 일치해도 부모 NavLink가 활성화되지 않도록 함
<NavLink to="home" end>home</NavLink>

2.6 <Navigate>

렌더링될 때 자동으로 경로를 변경하는 컴포넌트입니다. replace 속성으로 push/replace 모드를 제어합니다.

import React, { useState } from 'react';
import { Navigate } from 'react-router-dom';

export default function Home() {
  const [sum, setSum] = useState(1);
  return (
    <div>
      <h3>Home 콘텐츠</h3>
      {sum === 1 ? <h4>sum 값: {sum}</h4> : <Navigate to="/about" replace={true} />}
      <button onClick={() => setSum(2)}>sum을 2로 변경</button>
    </div>
  );
}

2.7 <Outlet>

중첩 라우트에서 자식 라우트가 렌더링될 위치를 지정하는 컴포넌트입니다. Vue의 <router-view>와 유사합니다.

// 라우트 테이블 생성
const element = useRoutes([
  { path: '/about', element: <About /> },
  {
    path: '/home',
    element: <Home />,
    children: [
      { path: 'news', element: <News /> },
      { path: 'message', element: <Message /> }
    ]
  }
]);

// Home.js
import React from 'react';
import { NavLink, Outlet } from 'react-router-dom';

export default function Home() {
  return (
    <div>
      <h2>Home 컴포넌트</h2>
      <div>
        <ul className="nav nav-tabs">
          <li><NavLink to="news">News</NavLink></li>
          <li><NavLink to="message">Message</NavLink></li>
        </ul>
        <Outlet />  {/* 중첩 라우트가 여기에 렌더링됨 */}
      </div>
    </div>
  );
}

3. Hooks

3.1 useRoutes()

라우트 테이블을 기반으로 <Routes><Route>를 동적으로 생성합니다.

// src/routes/index.js
import About from '../pages/About';
import Home from '../pages/Home';
import { Navigate } from 'react-router-dom';

export default [
  { path: '/about', element: <About /> },
  { path: '/home', element: <Home /> },
  { path: '/', element: <Navigate to="/about" /> }
];

// App.jsx
import React from 'react';
import { NavLink, useRoutes } from 'react-router-dom';
import routes from './routes';

export default function App() {
  const element = useRoutes(routes);
  return (
    <div>
      {/* ... */}
      {element}
      {/* ... */}
    </div>
  );
}

3.2 useNavigate()

프로그래매틱 네비게이션을 위한 함수를 반환합니다.

import React from 'react';
import { useNavigate } from 'react-router-dom';

export default function Demo() {
  const navigate = useNavigate();
  const handle = () => {
    // 방식 1: 특정 경로로 이동
    navigate('/login', { replace: false, state: { a: 1, b: 2 } });
    // 방식 2: 숫자로 앞/뒤로 이동 (history.go()와 유사)
    navigate(-1);
  };
  return (
    <div>
      <button onClick={handle}>버튼</button>
    </div>
  );
}

3.3 useParams()

현재 경로의 URL 파라미터(params)를 반환합니다. 5.x의 match.params와 동일합니다.

import React from 'react';
import { Routes, Route, useParams } from 'react-router-dom';
import User from './pages/User.jsx';

function ProfilePage() {
  const { id } = useParams(); // URL에서 params 추출
  return <div>사용자 ID: {id}</div>;
}

function App() {
  return (
    <Routes>
      <Route path="users/:id" element={<User />} />
    </Routes>
  );
}

3.4 useSearchParams()

현재 URL의 쿼리 문자열을 읽고 수정합니다. 반환값은 배열 [searchParams, setSearchParams]입니다.

import React from 'react';
import { useSearchParams } from 'react-router-dom';

export default function Detail() {
  const [search, setSearch] = useSearchParams();
  const id = search.get('id');
  const title = search.get('title');
  const content = search.get('content');
  return (
    <ul>
      <li>
        <button onClick={() => setSearch('id=008&title=하하&content=히히')}>
          검색 파라미터 업데이트
        </button>
      </li>
      <li>메시지 번호: {id}</li>
      <li>메시지 제목: {title}</li>
      <li>메시지 내용: {content}</li>
    </ul>
  );
}

3.5 useLocation()

현재 location 객체를 반환합니다. 5.x의 라우트 컴포넌트 location prop과 동일합니다.

import React from 'react';
import { useLocation } from 'react-router-dom';

export default function Detail() {
  const loc = useLocation();
  console.log(loc);
  // 출력 예시:
  // { hash: "", key: "ah9nv6sz", pathname: "/login", search: "?name=zs&age=18", state: {a:1, b:2} }
  return (
    <ul>
      <li>메시지 번호: {id}</li>
      <li>메시지 제목: {title}</li>
      <li>메시지 내용: {content}</li>
    </ul>
  );
}

3.6 useMatch()

현재 경로와 특정 패턴의 매칭 정보를 반환합니다. 5.x의 match prop과 유사합니다.

<Route path="/login/:page/:pageSize" element={<Login />} />
<NavLink to="/login/1/10">로그인</NavLink>

export default function Login() {
  const match = useMatch('/login/:x/:y');
  console.log(match);
  // 출력 예시:
  // { params: {x: '1', y: '10'}, pathname: "/LoGin/1/10", pattern: { path: '/login/:x/:y', caseSensitive: false, end: false } }
  return <h1>Login</h1>;
}

3.7 useInRouterContext()

컴포넌트가 <Router> 컨텍스트 내부에서 렌더링되었는지 여부를 boolean으로 반환합니다.

3.8 useNavigationType()

현재 페이지로 이동한 방식을 반환합니다. 반환값: "POP", "PUSH", "REPLACE". "POP"은 브라우저에서 직접 주소를 입력하거나 새로고침한 경우입니다.

3.9 useOutlet()

현재 컴포넌트에 렌더링된 중첩 라우트 객체를 반환합니다. 중첩 라우트가 없으면 null을 반환합니다.

const outlet = useOutlet();
console.log(outlet); // 중첩 라우트가 있으면 객체, 없으면 null

3.10 useResolvedPath()

주어진 URL 값의 path, search, hash를 해석하여 반환합니다.

태그: React Router useRoutes useNavigate useParams useSearchParams

8월 12일 12:08에 게시됨