Taeyoung Kim

Engineering

React Router (Data Mode) 핵심 개념

React Router (Data Mode) 핵심 개념 학습 내용을 정리한 백필 노트입니다.

이 글은 2025년 학습 기록을 블로그 형식으로 정리한 백필 노트입니다.

이 문서는 React Router v7.5.0의 Data Mode를 기준으로, React 애플리케이션에서 페이지를 관리하고 내비게이션을 구현하는 핵심 개념과 사용법을 정리합니다.

1. 기본 설치 및 구성

  1. **설치:**Bash

    npm install react-router
    
  2. 라우터 생성 (/src/routes/index.tsx):

    • createBrowserRouter 함수에 라우트(경로) 정보를 배열로 전달하여 라우터 객체를 생성합니다.
    • 각 라우트 객체는 path(경로)와 element(렌더링할 컴포넌트)를 가집니다.
  3. **애플리케이션에 적용 (/src/main.tsx):**TypeScript

    • RouterProvider 컴포넌트를 사용하여 생성한 라우터 객체를 앱 전체에 적용합니다.
    // /src/routes/index.tsx
    import { createBrowserRouter, RouterProvider } from 'react-router';
    import Home from './pages/Home';
    import About from './pages/About';
    
    const router = createBrowserRouter([
      { path: '/', element: <Home /> },
      { path: '/about', element: <About /> }
    ]);
    
    export default function Router() {
      return <RouterProvider router={router} />;
    }
    

2. 레이아웃과 중첩 라우팅

  • 레이아웃 컴포넌트: 여러 페이지에서 공통으로 사용될 헤더, 푸터 등을 포함하는 컴포넌트입니다.

  • &lt;Outlet>: 레이아웃 컴포넌트 내부에 위치하며, 자식 라우트의 컴포넌트가 렌더링될 자리를 지정합니다.

  • 중첩 구조: 라우트 설정에서 부모 라우트의 children 속성에 자식 라우트 배열을 정의하여 계층적인 UI 구조를 만듭니다.

  • &lt;ScrollRestoration>: 레이아웃 최상위에 추가하여 페이지 이동 시 스크롤 위치를 자동으로 복원하거나 최상단으로 이동시키는 기능을 활성화합니다.TypeScript

    // /src/routes/index.tsx
    const router = createBrowserRouter([
      {
        element: <DefaultLayout />, // 부모 레이아웃
        children: [ // 자식 라우트
          { path: '/', element: <Home /> },
          { path: '/about', element: <About /> }
        ]
      }
    ]);
    
    // /src/routes/layouts/Default.tsx
    export default function DefaultLayout() {
      return (
        <>
          <TheHeader />
          <Outlet /> {/* 이 위치에 Home 또는 About 컴포넌트가 렌더링됨 */}
          <ScrollRestoration />
        </>
      );
    }
    

3. 탐색 (Navigation)

컴포넌트 기반 탐색

  • &lt;Link to="/path">: 페이지 전체를 새로고침하지 않고 클라이언트 사이드에서 페이지를 이동시키는 기본 컴포넌트입니다.
    • replace: 브라우저 히스토리에 현재 경로를 남기지 않고 이동합니다.
    • preventScrollReset: &lt;ScrollRestoration>의 스크롤 복원 기능을 일시적으로 비활성화합니다.
  • &lt;NavLink to="/path">: &lt;Link>의 확장 버전으로, 현재 경로와 일치할 때 자동으로 active 클래스를 추가하여 활성 상태를 표시할 수 있습니다.
    • className=&#123;(&#123; isActive &#125;) => ...&#125;: 활성 상태(isActive)에 따라 동적으로 클래스를 적용할 수 있습니다.
    • end: 경로가 정확히 일치할 때만 활성 상태로 만듭니다. (하위 경로에서는 비활성)
  • &lt;Navigate to="/path">: 렌더링되는 즉시 지정된 경로로 리다이렉션시키는 컴포넌트입니다.

프로그래밍 방식 탐색

  • useNavigate(): Maps 함수를 반환하는 훅입니다.
    • Maps('/path'): 지정된 경로로 이동합니다.
    • Maps(-1): 뒤로 가기, Maps(1): 앞으로 가기.
  • redirect(): 라우트의 loader 함수 내에서 사용되어 특정 조건에 따라 다른 페이지로 리다이렉션시킵니다.

4. 라우팅 주요 기능

  • 동적 세그먼트 (:param):
    • URL의 일부를 변수로 사용하기 위해 path: '/movies/:movieId'와 같이 경로를 정의합니다.
    • useParams() 훅을 사용하여 컴포넌트 내에서 &#123; movieId &#125;와 같이 값을 추출할 수 있습니다.
  • 찾을 수 없는 페이지 (404):
    • path: '*'를 사용하여 일치하는 경로가 없을 때 보여줄 컴포넌트를 지정합니다. 이 라우트는 반드시 가장 마지막에 위치해야 합니다.
  • 보호된 경로 (Protected Route)와 loader:
    • 인증이 필요한 페이지에 loader 속성으로 비동기 함수를 지정합니다.
    • loader 함수는 페이지가 렌더링되기 전에 실행되어 사용자 인증 상태를 확인합니다.
    • 인증되지 않은 경우, redirect() 함수를 사용하여 로그인 페이지로 이동시킵니다. 이때, 원래 가려던 경로를 쿼리스트링(?redirectTo=...)으로 전달할 수 있습니다.
    • 인증된 경우, 사용자 정보를 반환할 수 있으며, 이 데이터는 useLoaderData() 훅을 통해 컴포넌트에서 접근할 수 있습니다.

5. 고급 기능: 페이지 전환 애니메이션

  • framer-motion 라이브러리를 사용하여 페이지 전환 시 애니메이션을 구현할 수 있습니다.
  • &lt;AnimatePresence>: 컴포넌트가 DOM에서 제거될 때 exit 애니메이션을 실행할 수 있게 합니다.
  • &lt;motion.div>: 애니메이션을 적용할 대상을 감싸며 initial, animate, exit 등의 속성으로 애니메이션 상태를 정의합니다.
  • useOutlet()useLocation(): 레이아웃 컴포넌트에서 useOutlet()으로 렌더링될 자식 컴포넌트를, useLocation().pathname으로 고유한 key를 가져와 AnimatePresence와 함께 사용하여 페이지 전환을 감지하고 애니메이션을 적용합니다.

6. 배포 설정

BrowserRouter를 사용하는 앱은 어떤 URL로 직접 접근하더라도 index.html을 먼저 서빙하도록 서버 설정이 필요합니다.

  • **Vercel (vercel.json):**JSON

    { "rewrites": [{ "source": "/:path*", "destination": "/index.html" }] }
    
  • Netlify (public/_redirects):

    /* /index.html 200

  • **Firebase (firebase.json):**JSON

    { "hosting": { "rewrites": [{ "source": "**", "destination": "/index.html" }] } }