[React] react-router-dom (1)

SungWoo·2024년 11월 12일

React

목록 보기
4/16
post-thumbnail

react-router-dom

React 애플리케이션에서 부드러운 화면 전환을 위해 사용하는 라이브러리

단일 페이지 애플리케이션(SPA)에서 페이지 전환을 부드럽게 만들어준다.


1. Client Side Routing

전통적인 웹사이트

  1. 사용자가 링크를 클릭하면 브라우저는 서버에 새로운 문서를 요청
  2. CSS와 JavaScript 파일을 다운로드하고 파싱
  3. 서버가 보내준 HTML을 렌더링
  4. 사용자가 링크를 클릭 시 새 페이지에 대한 프로세스가 다시 시작 (즉, 다른 페이지로 이동할 때마다 반복)

클라이언트 측 라우팅

  • 사용자가 링크를 클릭할 때 서버에 새로운 문서를 요청하지 않음
  • 애플리케이션은 즉시 새로운 UI를 렌더링하고 필요한 데이터가 있을 시 fetch 등을 통해 서버에서 데이터를 받아와 페이지에 업데이트 함
import * as React from "react";
import { createRoot } from "react-dom/client";
import {
  createBrowserRouter,
  RouterProvider,
  Route,
  Link,
} from "react-router-dom";

const router = createBrowserRouter([
  {
    path: "/",
    element: (
      <div>
        <h1>Hello World</h1>
        <Link to="about">About Us</Link>
      </div>
    ),
  },
  {
    path: "about",
    element: <div>About</div>,
  },
]);

createRoot(document.getElementById("root")).render(
  <RouterProvider router={router} />
);

장점

  • 브라우저가 새로운 문서나 CSS, JavaScript 파일을 매번 다시 요청하지 않아도 되므로 페이지 로딩 속도가 훨씬 빨라짐
  • 애니메이션과 같은 더 동적인 사용자 경험 제공 가능

2. Nested Routes

URL의 구조를 컴포넌트 계층 구조와 일치하도록 설정하여, 부모 경로 아래에 자식 경로를 추가하는 방식

중첩 라우트 설정 방법

1) JSX로 설정하기

createBrowserRoutercreateRoutesFromElements`를 사용해 JSX 문법으로 중첩된 라우트를 설정하는 방법

createBrowserRouter(
  createRoutesFromElements(
    <Route path="/" element={<Root />}>
      <Route path="contact" element={<Contact />} />
      <Route
        path="dashboard"
        element={<Dashboard />}
        loader={({ request }) =>
          fetch("/api/dashboard.json", {
            signal: request.signal,
          })
        }
      />
      <Route element={<AuthLayout />}>
        <Route
          path="login"
          element={<Login />}
          loader={redirectIfUser}
        />
        <Route path="logout" action={logoutUser} />
      </Route>
    </Route>
  )
);
  • 위 코드에서는 Root 컴포넌트 하위에 여러 중첩 라우트를 정의함.
  • /dashboard 경로는 Dashboard 컴포넌트를 렌더링하며, 데이터를 로드하기 위해 api/dashboard.json으로 fetch요청을 보냄.

2) 객체로 설정하기

객체를 사용하여 중첩 라우트를 설정하는 방법

createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    children: [
      {
        path: "contact",
        element: <Contact />,
      },
      {
        path: "dashboard",
        element: <Dashboard />,
        loader: ({ request }) =>
          fetch("/api/dashboard.json", {
            signal: request.signal,
          }),
      },
      {
        element: <AuthLayout />,
        children: [
          {
            path: "login",
            element: <Login />,
            loader: redirectIfUser,
          },
          {
            path: "logout",
            action: logoutUser,
          },
        ],
      },
    ],
  },
]);
  • 이 방법도 동일한 구조로 /contact, /dashboard, /login 등의 중첩 라우트를 설정하며, 데이터를 불러오거나 특정 조건을 만족해야 접근할 수 있는 구조를 설정할 수 있다.

3. Dynamic Segments

URL에서 변하는 부분을 변수처럼 다루는 기능

경로에 :parameterName 형식으로 선언하여 URL이 변경될 때 해당 값을 컴포넌트에 전달할 수 있다.

예시: 쇼핑몰의 제품 상세 페이지에서 각 제품의 ID를 URL로 전달하는 경우.

  • URL 구조: /products/:productId와 같이 설정하여 :productId 부분이 동적으로 변경되도록 설정한다.
  • /products/1로 접근하면 productId가 1로 전달되고, /products/2로 접근하면 2가 전달된다.
import { BrowserRouter, Routes, Route, useParams } from "react-router-dom";

function ProductDetail() {
  const { productId } = useParams(); // 동적 세그먼트 값 가져오기
  return <h2>Product ID: {productId}</h2>;
}

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="products/:productId" element={<ProductDetail />} />
      </Routes>
    </BrowserRouter>
  );
}
  • 사용자가 /products/5로 이동하면 productId가 5로 설정되며, 화면에 "Product ID: 5"가 표시된다.

4. Ranked Route Matching

여러 경로가 URL과 일치할 때 가장 구체적으로 일치하는 라우트를 자동으로 선택하는 기능

React Router는 URL 세그먼트 수, 정적 세그먼트(고정된 값), 동적 세그먼트(변수), 스플랫(*) 세그먼트 등 다양한 요소를 기준으로 라우트의 순위를 매겨 가장 구체적인 일치 항목을 선택하기 때문에, 라우트를 선언하는 순서에 관계없이 최적의 경로가 선택된다.

예시: /teams/new와 /teams/:teamId 라우트를 정의했을 때.

URL이 /teams/new로 들어오면 newteamId로 취급할 수도 있지만, 더 구체적인 경로인 /teams/new를 선택하도록 React Router의 매칭 알고리즘이 우선순위를 설정한다.

import { BrowserRouter, Routes, Route } from "react-router-dom";

function TeamNew() {
  return <h2>Creating a new team</h2>;
}

function TeamDetail() {
  const { teamId } = useParams();
  return <h2>Team ID: {teamId}</h2>;
}

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="teams/new" element={<TeamNew />} />
        <Route path="teams/:teamId" element={<TeamDetail />} />
      </Routes>
    </BrowserRouter>
  );
}

URL이 /teams/new로 들어오면 TeamNew 컴포넌트가 렌더링된다. 즉, React Router가 자동으로 더 구체적인 경로를 인식하여 /teams/:teamId보다 /teams/new를 먼저 매칭하는 것을 알 수 있다.

출처: https://reactrouter.com/en/main/start/overview#client-side-

profile
어제보다 더 나은

0개의 댓글