Frontend/React

[React] React Router Dom V6.4

khakhalog 2023. 5. 19. 17:58

1. BrowserRouter

react 프로젝트에 React Router를 적용할 때 React Router Dom에 내장되어 있는 BrowserRouter 컴포넌트로 감싸준다.

이 컴포넌트는 Histroy API를 사용하지 않고도 url을 변경하고 현재 주소의 경로에 관련된 정보를 리액트 컴포넌트에서 사용할 수 있도록 도와준다.

1.1 Router.tsx

Route 컴포넌트를 통해 path, element를 지정해주고 url을 분기처리해준다.

Route 컴포넌트는 Routes로 감싸줘야함.

// Router.tsx

import { BrowserRouter, Route, Routes } from "react-router-dom";
import Header from "../Components/Header";
import About from "./About";
import Home from "./Home";

function Router() {
  return (
    <BrowserRouter>
      <Header />
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </BrowserRouter>
  );
}
export default Router;

1.2 Header.tsx

HeaderLink 컴포넌트를 가져와서 to에 지정한 url로 페이지 라우터가 가능하도록 할 수 있다.

Link 컴포넌트도 BrowserRouter 내부에 위치해야한다.

// Header.tsx

import { Link } from "react-router-dom";

function Header() {
  return (
    <header>
      <ul>
        <li>
          <Link to={"/"}>Home</Link>
        </li>
        <li>
          <Link to={"/about"}>About</Link>
        </li>
      </ul>
    </header>
  );
}
export default Header;

2. createBrowserRouter

  • React-Router-Dom 6.4에 새롭게 추가된 방식.
  • Route를 중첩된 경로가 있는 객체의 배열로 나타낼 수 있다.

첫번째 Route는 Root 컴포넌트로, 하위 라우터들의 부모와 같은 역할을 하며, Childern 값으로 라우트를 지정해주면

위와 같은 구조로 렌더링되게 만들 수 있다.

2.1 Router.tsx

import { createBrowserRouter } from "react-router-dom";
import Root from "./Root";
import About from "./screens/About";
import Home from "./screens/Home";

// Router를 array 형식으로 표현할 수 있다.
const Router = createBrowserRouter([
  // 첫번째 Route는 전체 route들의 컨테이너와 같은 역할
  {
    path: "/",
    element: <Root />,
    children: [
      // Root 컴포넌트 내에서 path에 따라 Home, About 컴포넌트를 렌더링 해주는 것
      { path: "", element: <Home /> },
      { path: "about", element: <About /> },
    ],
  },
]);

export default Router;

2.2 Root.tsx

CreatBrowserRouter에서 children을 지정해주려면 Outlet 컴포넌트를 꼭 렌더링해줘야 한다.

import React from "react";
import { Outlet } from "react-router-dom"; // router 컴포넌트에서 children 속성 사용하기 위함

function Root() {
  return (
    <div>
      <Outlet />
    </div>
  );
}

export default Root;

2.3 Index.tsx

RouterProvider로 위에서 만든 Router를 전달하여 렌더링 해준다.

import React from "react";
import ReactDOM from "react-dom/client";
import { RouterProvider } from "react-router-dom";
import Router from "./Router";

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement
);
root.render(
  <React.StrictMode>
    {/* router props로 creteBrowserRouter로 만든 컴포넌트를 넘겨준다. */}
    <RouterProvider router={Router} />
  </React.StrictMode>
);

3. UseNavigate

Link 는 클릭시 페이지 이동이라면,

UseNavigate 훅을 통해서 로그인이나 특정 상태 변경시 사용자가 별다른 동작을 취하지 않아도 페이지 이동이 가능하다.

// Header.tsx

import { Link, useNavigate } from "react-router-dom";

function Header() {
  const navigate = useNavigate();
  const onAboutClick = () => {
    navigate("/about");
  };

  return (
    <header>
      <ul>
        <li>
          <Link to={"/"}>Home</Link>
        </li>
        <li>
          <button onClick={onAboutClick}>About</button>
        </li>
      </ul>
    </header>
  );
}
export default Header;

위에서는 버튼 클릭시 onClick 이벤트를 통해 useNavigate 훅을 실행했지만 로그인, 로그아웃 등 효율적으로 사용 가능할 것 같다.


4. UseParams

라우트 이동시 특정 파라미터를 넘겨준다면 UseParams를 통해 가져와서 활용할 수 있다.

4.1 Router.tsx

컴포넌트를 userId 파라미터에 따라 다른 화면을 렌더링해줄 수 있다.

여기서 주의할 점은 만약 '/users' 로 접근하면 컴포넌트를 렌더링하게 된다.

'/users' 로 접근했을 때 보여줄 화면이 있다면,

{path : "users", element : , children : \[ .....\]}

이런식으로 구성할 수 있다.

const Router = createBrowserRouter([
  // 첫번째 Route는 전체 route들의 컨테이너와 같은 역할
  {
    path: "/",
    element: <Root />,
    children: [
      // Root 컴포넌트 내에서 path에 따라 Home, About 컴포넌트를 렌더링 해주는 것
      { path: "", element: <Home />, errorElement: <ErrorComponent /> },
      { path: "about", element: <About /> },
      { path: "users/:userId", element: <Users /> },
    ],
    errorElement: <NotFound />,
  },
]);

4.2 Users.tsx

useParams를 통해 파라미터로 넘겨준 userId를 가져와서 사용할 수 있따.

import { useParams } from "react-router-dom";
import { users } from "../../db";

function Users() {
  const { userId } = useParams();

  return (
    <h1>
      User with it {userId} is named : {users[Number(userId) - 1].name}
    </h1>
  );
}

export default Users;

5. UseOutletContext

Outlet 컴포넌트로 컴포넌트 내에 하위 라우트를 children으로 지정하면서, context props를 통해 하위 라우트와 공유할 상태나 값을 넘겨줄 수 있다.

하위 컴포넌트에서는 UseOutletContext 훅을 통해 넘겨준 값을 가져와서 사용할 수 있다.

5.1 Users.tsx

context로 이름을 넘겨준다.

import { Outlet, useParams, Link } from "react-router-dom";
import { users } from "../../db";

function Users() {
  const { userId } = useParams();

  return (
    <div>
      <h1>
        User with it {userId} is named : {users[Number(userId) - 1].name}
      </h1>
      <hr />
      <Link to="followers">See Followers</Link>
      <Outlet context={{ nameOfMyUser: users[Number(userId) - 1].name }} />
    </div>
  );
}

5.2 Router.tsx

Users 컴포넌트의 하위 라우트 Followers 컴포넌트를 연결해준다.

import { createBrowserRouter } from "react-router-dom";
import ErrorComponent from "./Components/ErrorComponent";
import Root from "./Root";
import About from "./screens/About";
import Home from "./screens/Home";
import NotFound from "./screens/NotFound";
import Followers from "./screens/users/Followers";
import Users from "./screens/users/Users";

// Router를 array 형식으로 표현할 수 있다.
const Router = createBrowserRouter([
  // 첫번째 Route는 전체 route들의 컨테이너와 같은 역할
  {
    path: "/",
    element: <Root />,
    children: [
      { path: "", element: <Home />, errorElement: <ErrorComponent /> },
      { path: "about", element: <About /> },
      {
        path: "users/:userId",
        element: <Users />,
        children: [{ path: "followers", element: <Followers /> }],
      },
    ],
    errorElement: <NotFound />,
  },
]);

export default Router;

5.3 Followers.tsx

useOutletContext를 통해 위에서 상위 컴포넌트인 Users에서 Context를 통해 넘겨준 이름 값을 가져와서 사용해줄 수 있다.

import { useOutletContext } from "react-router-dom";

interface IFollowersContext {
  nameOfMyUser: string;
}

function Followers() {
  const { nameOfMyUser } = useOutletContext<IFollowersContext>();

  return <h1>Here are {nameOfMyUser}의 Followers</h1>;
}
export default Followers;

'Frontend > React' 카테고리의 다른 글

[React] React Query 톺아보기  (0) 2023.07.25
[React] Styledcomponents S-dot naming  (1) 2023.07.05
[React] Typescript + Inline style  (1) 2023.07.05
[React] Context API  (1) 2023.07.03
[React] CSS Reset  (2) 2023.01.08