🛣️
EPISODE 07
v6 · useParams · useNavigate · Outlet · 404
React Router
react-router-dom v6의 핵심(BrowserRouter/Routes/Route/Link), useParams/useNavigate/useLocation 훅, 중첩 라우트(Outlet), 404 처리, 그리고 보호된 라우트 패턴까지.
React RouterroutingOutlet
소요 시간
⏱ 45~60분
난이도
📊 중급
선수 조건
🎯 react-06
결과물
다중 페이지 + 중첩 레이아웃 + 404를 가진 SPA
이 강의에서 배우는 것
- 1BrowserRouter / Routes / Route 로 라우팅을 설정한다
- 2Link / NavLink로 페이지 전환을 한다
- 3useParams / useNavigate / useLocation 훅을 사용한다
- 4Outlet으로 중첩 레이아웃을 구성한다
- 5Navigate로 보호된 라우트를 만든다
1. 설치 & 핵심 컴포넌트
bash
npm install react-router-dom| 컴포넌트 | 역할 |
|---|---|
| <BrowserRouter> | 앱 전체를 감싸는 라우터 |
| <Routes> | 여러 <Route>를 담는 컨테이너 |
| <Route> | URL 패턴 ↔ 컴포넌트 |
| <Link> | 페이지 이동 (a 태그 대체) |
| <NavLink> | 현재 경로 일치 시 active |
| <Navigate> | 리다이렉트 |
| <Outlet> | 중첩 라우트 자식 렌더링 위치 |
2. 기본 라우팅
jsx
// main.jsx
import { BrowserRouter } from 'react-router-dom';
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);
// App.jsx
import { Routes, Route } from 'react-router-dom';
function App() {
return (
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/blog" element={<BlogPage />} />
<Route path="/blog/:id" element={<BlogPostPage />} /> {/* 동적 */}
<Route path="*" element={<NotFoundPage />} /> {/* 404 */}
</Routes>
);
}3. Link / NavLink
jsx
<Link to="/blog">블로그</Link>
<NavLink
to="/blog"
style={({ isActive }) => ({
color: isActive ? '#3b82f6' : '#374151',
fontWeight: isActive ? 'bold' : 'normal',
})}
>
블로그
</NavLink>4. useParams
jsx
import { useParams } from 'react-router-dom';
// path="/blog/:id"
function BlogPostPage() {
const { id } = useParams(); // 항상 문자열
return <h1>게시물 #{id}</h1>;
}5. useNavigate
jsx
import { useNavigate } from 'react-router-dom';
function LoginForm() {
const navigate = useNavigate();
const handleLogin = async () => {
await login();
navigate('/dashboard');
navigate(-1); // 뒤로
navigate('/login', { replace: true }); // 히스토리 교체
};
}6. useLocation
jsx
import { useLocation } from 'react-router-dom';
function App() {
const location = useLocation();
// location.pathname: '/blog/42'
// location.search: '?page=1'
// location.hash: '#section1'
// location.state: navigate()로 전달한 데이터
}7. Outlet — 중첩 라우트
jsx
<Routes>
<Route path="/blog" element={<BlogLayout />}>
<Route index element={<BlogListPage />} />
<Route path=":id" element={<BlogPostPage />} />
</Route>
</Routes>
function BlogLayout() {
return (
<div>
<nav>블로그 사이드바</nav>
<main>
<Outlet />
</main>
</div>
);
}8. Navigate — 보호된 라우트
jsx
import { Navigate } from 'react-router-dom';
function ProtectedRoute({ children }) {
const isLoggedIn = useAuthStore(state => state.isLoggedIn);
if (!isLoggedIn) return <Navigate to="/login" replace />;
return children;
}