Home React Router 시작하기
Post
Cancel

React Router 시작하기

React Router의 초기 설정과 BrowserRouter, RouterProvider, useRouteError, Outlet, Link, useParams, 그리고 Routing Layer

React Router Dom

Single-Page React 앱에서, 라우팅은 전체 페이지를 다시 로드하지 않고 여러 페이지들 사이를 탐색하는 프로세스를 의미

React는 SPA(Single Page Application)

  • 렌더링을 SSR과 달리 클라이언트(브라우저)에서 처리
  • 모든 컴포넌트의 변화가 한 페이지 안에서 발
  • 다른 URL로 이동하는 것은 페이지를 교체하는 것이 아니라, 한 페이지 내부의 컴포넌트만 변경하는 것
  • URL은 고정됨
    • 페이지 즐겨찾기, 뒤로가기, 새로고침 등 불가
    • SEO 문제
  • React Router를 이용해 해결 가능
    • 사용자 경험 향상
1
npm install react-router-dom

Adding a Router

createBrowserRouter

  • DOM History API를 사용해 URL을 업데이트하고 history 스택을 관리
  • v6.4 데이터 API들을 활성화함
    • loaders, actions, fetchers

RouterProvider

  • 모든 데이터 라우터 객체는 이 컴포넌트에 전달되어 앱을 렌더링하고
  • 나머지 데이터 API를 활성화
  • fallbackElement로 사용자에게 앱이 작동 중이라는 표시 제공
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// src/main.jsx
import React from "react";
import ReactDOM from "react-dom/client";
import { useBrowserRouter, RouterProvider } from "react-router-dom";
import Root, { rootLoader } from "./routes/root";
import Team, { teamLoader } from "./routes/team";
import ErrorPage from "./error-page";

const router = createBrowserRouter([
  {
    path: "/", // 루트 경로. 루트 레이아웃 역할
    element: <Root />,
    errorElement: <ErrorPage />,
    loader: rootLoader,
    children: [{ path: "team", element: <Team />, loader: teamLoader }] // 하위 경로
  }
]);

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

useRouteError

  • errorElement 내부에서, action, loader, rendering 중에 발생한 모든 것을 반환하는 훅
  • 던져진 응답은 특별하게 처리됨

errorElement

  • 지정된 URL과 일치하는 경로가 없을 때 렌더링됨
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// src/error-page.jsx
import { useRouteError } from "react-router-dom";

function ErrorPage() {
  const error = useRouteError();

  return (
    <div id="error-page">
      <h1>Oops!</h1>
      <p>Sorry, an unexpected error has occurred.</p>
      <p>
        <i>{error.statusText || error.message}</i>
      </p>
    </div>
  );
}
export default ErrorPage;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { useRouteError } from "react-router-dom";
function ErrorBoundary() {
  const error = useRouteError();
  console.error(error);
  return <div id="error-page">{error.statusText || error.message}</div>;
}

<Route
  errorElement={<ErrorBoundary />}
  loader={() => {
    something.that.breaks(); // unexpected errors in loaders/actions
  }}
  action={() => {
    throw new Response("Bad Request", { status: 400 }); // stuff you throw on purpose in loaders/actions
  }}
  element={
    <div>{breaks.while.rendering}</div> // and errors thrown while rendering
  }
/>;

Nested Routes

Outlet

  • root route의 child로 만들어 중첩
  • Outlet을 이용해 해당 위치에 렌더링
1
import { Outlet } from "react-router-dom";
1
2
3
<div id="detail">
  <Outlet />
</div>

Client Side Routing

Link

  • 앱이 서버에 다른 문서를 요청하지 않고 URL을 업데이트
1
import { Link } from "react-router-dom";
1
<Link to={`contacts/1`}>클릭해서 넘어가기</Link>

##

useParams

Routing Layer 구현하기

Routing Layer

  • 경로를 관리하고, 적절한 페이지 구성 요소를 렌더링하는 FE React 앱의 일부
  • 사용자가 링크를 클릭하거나 주소 표시줄에 URL을 입력하면,
  • 라우팅 계층이 요청을 가로채고
  • 현재 경로를 기반으로 어떤 구성 요소나 보기를 렌더링해야 하는지 결정

PathConstants

  • 모든 페이지 경로를 포함하는 객체
1
2
3
4
5
const pathConstants = {
  TEAM: "/team",
  REPORT_ANALYSIS: "reports/:reportId/analysis"
  // ...
};

routes

  • 경로 문자열과 페이지 구성 요소 간의 매핑을 포함하는 배열
1
2
3
4
5
const routes = [
  { path: PathConstants.TEAM, element: <TeamPage /> },
  { path: PathConstants.REPORT_ANALYSIS, element: <ReportAnalysisPage /> }
  // ...
];
1
<Link to={PathConstants.TEAM}> 페이지로 이동</Link>

참고

Tutorial

How to Build a Routing Layer in React and Why You Need It

This post is licensed under CC BY 4.0 by the author.