React

리액트 라우터(React Router)란? ( install 설치 / createBrowserRouter 사용법)

hihiha2 2023. 9. 1. 03:00

🧷 정의

리액트 라우터(React Router)란?

React 애플리케이션에서 클라이언트 측 라우팅을 구현하는 데 사용되는 라이브러리.

단일 페이지 애플리케이션(Single Page Application, SPA)을 개발할 때, 사용자가 다양한 URL로 이동하거나 페이지를 변경할 수 있도록 도와주는 라이브러리

 

(라우팅: 웹 애플리케이션에서 다른 페이지로 사용자를 네비게이션하는 프로세스)

 

 

 

 

🧷원리와 주요기능

라우터를 정확하게 이해하기에 앞서, window.loacation에 대해 공부하였다.

location과 URL에 대한 이해가 있다면 리액트 라우터에 대해서 더 이해가 잘 될 것이라고 생각한다.

 

 

window.location ( Web API란? / pathname, search, hash ... )

Web APIs에는 종류가 정말 많은데 오늘은 그 중 window.locaion에 대해 공부했다. 우선 window.location을 이해하기 위해서는 Web APIs가 무엇인지 이해하는 것이 필요하다. 🧷선행학습 web API란? 우선 mdn의 공

hihiha2.tistory.com

 

 

 

1. 컴포넌트 기반: 화면을 다른 경로로 전환할 때마다 React 컴포넌트를 렌더링하고 업데이트하는 방식으로 작동

2. URL감시: 현재 URL을 감시하고, URL이 변경될 때마다 라우팅을 처리한다. 

(useLocation훅을 통해 location객체에 접근한다. 객체를 통해 현재 경로, 쿼리 문자열 및 해시를 읽어와서 필요한 작업을 수행할 수 있다. URL의 변경은 브라우저 history API를 사용하여 처리되며, 사용자가 링크를 클릭하거나 자바스크립트 코드에서 프로그래밍 방식으로 URL을 변경할 때마다 이벤트가 발생한다.)

 

 

3. 매칭과 렌더링: 현재 URL을 등록된 경로와 비교하여 가장 일치하는 경로에 연결하여 컴포넌트를 렌더링한다.

path: "/search"경로로 이동하면, <SearchPage />컴포넌트로 연결된 Searech 컴포넌트가 렌더링된다.

 

4. 중첩라우팅: 중첩된 라우트를 지원하여 복잡한 애플리케이션 구조를 보다 쉽게 처리한다.

 

5. 리다이렉션과 404처리: <Redirect> 컴포넌트를 사용하여 리다이렉션을 처리하고, 없는 경로로 접근할 때 404페이지를 표시하여 오류처리를 지원한다.

 

6. 브라우저 history관리:  브라우저의 history를 관리하여 뒤로가기와 앞으로 가기를 지원하고, 브라우저의 주소 히스토리를 변경하지 않으면서 URL을 업데이트한다.

 

7. 훅 사용: useHistory, useLocation, useParams, useRouteMatch등의 훅을 사용하여 한층 더 쉽게 URL을 관리하고 라우팅을 쉽게 해준다.

(리액트 라우터의 주요 훅들에 대해서는 추후에 다시 포스팅을 할 예정이다.)

 

 


 

💿 install

 

기존의 BrowserRouter방식에서 createBrowserRouter방식으로 변경되었기때문에 최신버전으로 다운 받는 것이 좋다.

 

 

1. 최신버전 설치

 

npm

npm install react-router-dom@latest

 

yarn

yarn add react-router-dom@latest

 

 

만약, 이미 다운을 받았다면 내가 받은 라우터가 최신버전인지를 확인한다.

 

 

2. 버전확인

package.json 파일을 열어 React Router 패키지의 버전을 확인할 수 있습니다

"dependencies": {
  "react-router-dom": "^5.2.0"
}

 

 

npm

npm show react-router-dom version

 

yarn

yarn info react-router-dom version

 

 

 

버전이 오래되었다면, 터미널에서 아래의 코드를 통해 이전버전을 제거하고 다시 최신버전으로 다운 받는다.

 

 

 

3. 이전버전 제거

 

npm

npm uninstall react-router-dom

 

yarn

yarn remove react-router-dom

 

 

 


라우터 6.4v 에서는 createBrowserRouter방식을 권장하고 있기때문에 createBrowserRouter방식으로 만드는 것이 좋다.

 

 

🕹사용법

🧷 개요

- Router.js : path에 맞는 element를 매칭하여 내보내는 역할.

react-router-dom에서 createBrowserRouter를 import한다.

각 페이지에서 보여줄 path와 element, 중첩라우팅을 위한 children을 적는다.

 배열안에 담긴 객체형태로 담아서 export한다.

(가장 상단의 페이지가 부모, children으로 들어오는 페이지가 자식페이지이다. 부모 ➡️ 자식은 path가 이어진다고 생각하면 된다.

ex> 부모 /movie, 자식 /movie/detail, /movie/video ....)

- index.js: 어떤 것을 렌더링하여 돔에 그릴지(render)를 적는다.

 Router.js에서 만든 router와 react-router-dom의 RouterProvider를 import한다.

ReactDOM.createRoot를 이용해서 render할 값에 RouteProvider를 넣고, router에 Router에서 import해온 값을 넣는다.

 

- App.js: 전체적인 Layout을 보여주는 컴포넌트

모든 컴포넌트들의 부모 컴포넌트(App.js)에 Outlet를 이용하여(import), 고정적인 컴포넌트가 아닌 계속 변경되어야하는 하위컴포넌트로넣어줄 수 있다.

 

 

 

 

🧷 디테일한 순서

- Router.js

1. src의 하위파일로 Router.js생성한다.

2. createBrowserRouter를 import한다.

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

3. 전체 컴포넌트의 root가 될 최상위 컴포넌트를 import한다.

(App.js로 만들어도 되고, Root.js로 만들어도 된다.)

 

4. 라우팅 하고 싶은 각각의 페이지들을 모두 import한다.

(아래의 예시에서는 NotFound, MainPage, DetailPage, SearchPage)

 

5. router라는 이름의 변수를 선언하고 export한다. 

router는 createBrowserRouser()안에 라우팅할 각 페이지를 담는다.

최상위 역할을 할 컴포넌트를 가장 상단에 적고 하위 컴포넌트들을 children안에 적는다.

(path에 따라서 매칭되는 element에 적힌 컴포넌트가 화면에 렌더링될 것이다.)

 

시작페이지를 지정할때는 index: true를 적어도 되고 path를 ""로 적어도 된다.

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

// App.js를 Root.js로 만들 수 있다.
// import Root from "./routes/root";

import App from "./App";
import NotFound from "./pages/NotFound";
import MainPage from "./pages/MainPage/MainPage";
import DetailPage from "./pages/DetailPage/DetailPage";
import SearchPage from "./pages/SearchPage/SearchPage";

export const router = createBrowserRouter([

  {
    path: "/", 
    element: <App />, 
    errorElement: <NotFound />,
    children: [
      {
        1️⃣ index: true,  
        2️⃣ path: "", ⬅️ 시작페이지라서 ""임
        element: <MainPage />,
      },
      {
        path: ":movieId",
        element: <DetailPage />,
      },
      {
        path: "search",
        element: <SearchPage />,
      },
    ],
  },
]);

➡️ children을 통해서 중첩라우팅을 할 수 있다.

(부모로 부터 path가 이어진다.)

 

- index.js

1. src의 하위폴더로 index.js를 생성한다.

2. React, ReactDOM을 각각 import한다.

3. react-router-dom에서 RouteProvider를 import한다.

4. router를 Router.js에서 import한다.

5. ReactDOM.createRoot(...).render를 통해 router를 provider안에 넣는다.

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

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

 

 

❌ 주의할 점

원래 사용되던 ReactDOM.render는 더이상 지원되지 않으므로 사용하면 아래와 같은 메시지가 콘솔창에 뜬다.

ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17.

따라서 ReactDOM.createRoot를 사용하여 render하도록 한다.

 

 

 

- App.js

전체적인 레이아웃을 나타내는 페이지라고 생각하면 편하다!

1. src의 하위파일로 App.js를 생성한다.

(Root.js로 해도 된다.)

 

2. react-router-dom에서 Outlet을import한다.

 

3. 화면에 항상 렌더링되어야하지만 페이지전환을 필요로 하지 않는 것들은 이 페이지에 import하면 된다.

(Nav.js, Footer.js)

이렇게 루트파일에 적으면 라우팅과 상관없이 항상 화면에 뜨는 고정적인 컴포넌트가 될 것이다.

내비게이션과 푸터는 어떤 페이지로 전환되어도 항상 고정되어 있도록 만들고 싶기때문에 아래와 같이 만들었다.

import { Outlet } from "react-router-dom";
import Nav from "./components/Nav/Nav";
import Footer from "./components/Footer/Footer";
import "./App.css";

function App() {
  return (
    <div className="App">
      <Nav /> ⬅️ 고정
      <Outlet /> ⭐️ URL에 따라 변경되는 부분 ⭐️
      <Footer /> ⬅️ 고정
    </div>
  );
}

export default App;

 

4. 화면에서 URL변경에 따라 다르게 보여주고 싶은 것들을 <Nav /> <Footer /> 컴포넌트 사이에 <Outlet /> 을 사용하여 넣는다.

 

➡️  Outlet을 사용하여 url에 따라서 변경되어야하는 부분만 손쉽게 페이지전환이 가능

 

 

 

 

🙋‍♀️ 내 생각

리액트 라우터 라이브러리를 통해, 각 path에 맞는 컴포넌트를 element로 쉽게 연결할 수 있다. 그리고 해당 역할을 하는 파일을 Router.js, index.js, App.js로 각각 나눠서 코드를 짬으로써 가독성을 높이고 유지보수를 쉽게 할 수 있다는 장점이 있다.

children을 통해서 중첩라우팅, Outlet을 통해서 변경되어야할 부분과 그렇지 않은 부분을 모두 가독성높게 표기할 수 있다.

컴포넌트기반으로 구조화 모듈화할 수 있고, 중첩라우팅을 통해 URL을 계층적으로 구성할 수 있다. 

이외에도 useParams를 통한 동적 라우팅, useNavigate을 통한 손쉬운 내비게이션등의 기능이 있다.

 

리액트에서 사용되는 훅들과 중첩라우팅에 대해서는 추후에 더 공부하고 정리하여 다시 포스팅할 예정이다.