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를 해석하여 반환합니다.