누구나 로고
Online CoursesFor BusinessLibraryTrend InsightsFree coursesNoticesContactCareers
모든 강의를 무료로 볼 수 있어요. 회원가입 없이도 학습 가능합니다.
로그인무료 회원가입
강좌리액트 입문 — 컴포넌트로 만드는 웹20강

20강 / 전체 28강

리스트 앱 실전 ②

5분 읽기 조회 0

React Router v6로 SPA에서 여러 페이지를 구현하는 방법, 동적 라우팅, 중첩 라우팅, useNavigate, useParams를 실전 예제로 배웁니다.

🗺️ 클라이언트 사이드 라우팅이란

SPA에서 URL이 바뀌어도 전체 페이지를 서버에서 다시 받지 않습니다. 자바스크립트가 URL 변경을 감지하고 해당하는 컴포넌트를 렌더링합니다. 이것이 클라이언트 사이드 라우팅(CSR)입니다. React Router v6가 이를 담당합니다.

npm install react-router-dom

⚙️ 기본 설정

애플리케이션 진입점에서 라우터를 설정합니다:

// main.tsx
import { BrowserRouter } from 'react-router-dom'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
)

// App.tsx — 라우트 정의
import { Routes, Route } from 'react-router-dom'
import HomePage from './pages/HomePage'
import PostListPage from './pages/PostListPage'
import PostDetailPage from './pages/PostDetailPage'
import NotFoundPage from './pages/NotFoundPage'

function App() {
  return (
    <Routes>
      <Route path="/" element={<HomePage />} />
      <Route path="/posts" element={<PostListPage />} />
      <Route path="/posts/:postId" element={<PostDetailPage />} />  {/* 동적 라우팅 */}
      <Route path="*" element={<NotFoundPage />} />               {/* 404 */}
    </Routes>
  )
}

🔗 Link 컴포넌트 — 페이지 이동

일반 <a href> 태그를 쓰면 페이지 전체가 새로고침됩니다. React Router의 <Link>를 사용해야 합니다:

import { Link } from 'react-router-dom'

function Navigation() {
  return (
    <nav className="flex gap-6">
      <Link to="/" className="text-gray-700 hover:text-indigo-600">홈</Link>
      <Link to="/posts" className="text-gray-700 hover:text-indigo-600">게시글</Link>
    </nav>
  )
}

// NavLink: 현재 경로와 일치하면 active 스타일 자동 적용
import { NavLink } from 'react-router-dom'

function Sidebar() {
  return (
    <nav>
      <NavLink
        to="/posts"
        className={({ isActive }) =>
          isActive ? 'text-indigo-600 font-bold' : 'text-gray-600'
        }
      >
        게시글
      </NavLink>
    </nav>
  )
}

🔢 동적 라우팅 — useParams

URL에 :postId처럼 콜론을 붙이면 동적 파라미터입니다. useParams()로 읽습니다:

// PostDetailPage.tsx
import { useParams } from 'react-router-dom'

interface Post { id: number; title: string; body: string; userId: number }

export default function PostDetailPage() {
  const { postId } = useParams<{ postId: string }>()
  const { data: post, loading, error } = useFetch<Post>(
    `https://jsonplaceholder.typicode.com/posts/${postId}`
  )

  if (loading) return <div>불러오는 중...</div>
  if (error) return <div>오류: {error}</div>
  if (!post) return null

  return (
    <article className="max-w-2xl mx-auto p-6">
      <h1 className="text-2xl font-bold mb-4">{post.title}</h1>
      <p className="text-gray-600 leading-relaxed">{post.body}</p>
    </article>
  )
}

🧭 프로그래밍 방식 이동 — useNavigate

버튼 클릭 후 다른 페이지로 이동하거나, 로그인 후 리다이렉트할 때 사용합니다:

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

function LoginForm() {
  const navigate = useNavigate()

  async function handleLogin() {
    // 로그인 로직...
    navigate('/')          // 홈으로 이동
    navigate(-1)           // 뒤로 가기
    navigate('/dashboard', { replace: true })  // 히스토리 교체 (뒤로 가기 불가)
  }

  return <form onSubmit={handleLogin}>...</form>
}

📂 중첩 라우팅 — Outlet

대시보드처럼 공통 레이아웃 안에서 하위 페이지가 바뀌는 구조에 사용합니다:

// App.tsx
<Routes>
  <Route path="/admin" element={<AdminLayout />}>
    <Route index element={<AdminDashboard />} />       {/* /admin */}
    <Route path="users" element={<AdminUsers />} />    {/* /admin/users */}
    <Route path="posts" element={<AdminPosts />} />    {/* /admin/posts */}
  </Route>
</Routes>

// AdminLayout.tsx — Outlet이 하위 페이지를 렌더링하는 자리
import { Outlet, Link } from 'react-router-dom'

function AdminLayout() {
  return (
    <div className="flex">
      <aside className="w-48 bg-gray-800 text-white p-4">
        <Link to="/admin/users" className="block py-2">사용자</Link>
        <Link to="/admin/posts" className="block py-2">게시글</Link>
      </aside>
      <main className="flex-1 p-6">
        <Outlet />  {/* 하위 라우트 컴포넌트가 여기 렌더링 */}
      </main>
    </div>
  )
}

✅ 정리

  • BrowserRouter로 앱 전체를 감싸고, Routes/Route로 경로를 정의합니다.
  • 페이지 이동은 <Link to="/path">. 코드에서 이동은 useNavigate().
  • :파라미터로 동적 라우팅, useParams()로 읽습니다.
  • 중첩 라우팅: 부모 레이아웃에 <Outlet />을 배치합니다.

관련 주제

  • 완료 토글 기능
  • 삭제 기능
  • 필터링 구현
  • 상태 구조 리팩토링
  • 개발·프로그래밍
  • 개발·프로그래밍 강의
  • 리액트 입문 — 컴포넌트로 만드는 웹
  • 무료강의
  • 무료 온라인 강의
  • NUGUNA
  • 누구나
이전 19강리스트 앱 실전 ①다음 21강 라우팅 — React Router

댓글

0/1000

불러오는 중...

목차

  1. 1.리액트란 무엇인가
  2. 2.개발 환경 만들기 — Vite
  3. 3.JSX 기초
  4. 4.컴포넌트 만들기
  5. 5.Props로 데이터 전달
  6. 6.State와 useState
  7. 7.이벤트 처리
  8. 8.조건부 렌더링
  9. 9.리스트 렌더링과 key
  10. 10.폼 다루기
  11. 11.useEffect 기초
  12. 12.데이터 가져오기(fetch)
  13. 13.상태 끌어올리기
  14. 14.컴포넌트 합성과 재사용
  15. 15.useRef와 DOM 접근
  16. 16.커스텀 훅 만들기
  17. 17.Context API
  18. 18.useReducer
  19. 19.리스트 앱 실전 ①
  20. 20.리스트 앱 실전 ②
  21. 21.라우팅 — React Router
  22. 22.스타일링 방법들
  23. 23.리스트·상세 페이지 연결
  24. 24.비동기 상태 관리 패턴
  25. 25.성능 기초 — memo
  26. 26.에러 처리와 경계
  27. 27.환경변수와 빌드
  28. 28.배포하기

Support

  • Notices
  • FAQ
  • Contact Us
  • Community

Help & Info

  • Terms of Service
  • Privacy Policy
  • Refund Policy

Services

  • About Us
  • Sign up
  • New courses
  • Free courses
누구나 로고
Terms of ServicePrivacy PolicyRefund Policy

상호명: NUGUNA  |  대표자: 정우진  |  사업자등록번호: 392-32-01817  |  통신판매업신고: 제 2026-서울양천-0564 호

주소: 서울특별시 양천구 목동서로 100  |  이메일: nugunapass@gmail.com  |  전화: 010-6395-3043

© 2026 NUGUNA. All rights reserved.

KB예금주인증관리자
HomeCoursesLibraryContactMY