React Router Dom

2022. 12. 26. 21:42프로그래밍/React

React Router Dom

웹 앱에서 동적 라우팅을 구현 가능하게 해주는 라이브러리
컴포넌트 기반 라우팅을 용이하게 함

 

Single Page Application (SPA)

리액트는 SPA이기 때문에 하나의 index.html 템플릿 파일을 가짐
자바스크립트를 이용해 컴포넌트들을 이 하나의 템플릿에 넣어 페이지를 변경함
이때 React Router Dom 라이브러리가 새 컴포넌트로 라우팅/검색을 하고 렌더링에 도움을 줌

React Router Dom 설치

npm install react-router-dom --save
import { BrowserRouter } from 'react-router-dom';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
);

설치 완료 후 앱 어디서든 React Router를 사용할 수 있도록

src/index.js 파일에서 BrowserRouter 로 루트 요소를 감싸줌


BrowserRouter

HTML5 History API를 사용해 (pushState, replaceState/popState 이벤트)
페이지를 새로고침하지 않고도 주소를 변경할 수 있도록 해줌 (UI를 URL과 동기화된 상태로 유지)
function App() {
  return (
    <div className="App">
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="about" element={<About />} />
        <Route path="contact" element={<Contact />} />
      </Routes>
    </div>
  );
}

 

Routes

앱에서 생성될 모든 개별 경로에 대한 컨테이너/상위 역할

자식 컴포넌트 중에서 매칭되는 첫번째 Route를 렌더링 함

 

Route

단일 경로를 만들 경우 사용됨

경로 이름이 백슬래시인 컴포넌트는 앱이 처음 로드될 때마다 먼저 렌더링 됨

path : 원하는 컴포넌트의 URL 경로 지정

element : 경로에 맞게 렌더링 되어야 하는 컴포넌트 지정


중첩 라우팅 (Nested Routes)

Route 안에 또 다른 Route 를 작성
상세 페이지, 탭으로 구성된 페이지 구현에 용이함
부모 컴포넌트 안에서 자식 경로 요소가 렌더링 될 위치에 Outlet 사용
<BrowserRouter>
  <Routes>
    // App 컴포넌트에 Header/Footer 등 레이아웃
    <Route path="/" element={<App />} />
    
      // localhost:3000/ 경로 => Home 컴포넌트
      <Route index element={<Home />}>
      
      // localhost:3000/teams 경로 => Teams 컴포넌트
      <Route path="teams" element={<Teams />}>
        
        // localhost:3000/teams/13 경로 => Team 컴포넌트
        <Route path=":teamId" element={<Team />} />
        
        // localhost:3000/teams/new 경로
        <Route path="new" element={<NewTeamForm />} />
        
        // localhost:3000/teams 경로 => LeagueStandings 컴포넌트
        <Route index element={<LeagueStandings />} />
      </Route>
    </Route>
  </Routes>
</BrowserRouter>

Outlet

부모 경로 요소에서 자식 경로 요소를 렌더링하기 위해 사용함
하위 경로가 렌더링될 때 중첩된 UI가 표시될 수 있음

부모 라우트가 일치할 경우 자식 인덱스 라우트를 렌더링
만약 인덱스 라우트가 없으면 아무것도 렌더링하지 않음
// 부모 경로 요소 App 컴포넌트
function App() { 
  return (
    <div>
      <div className="content">
        // 자식 경로 요소
        <Outlet />
      </div>
    </div>
  );
}
// 루트 라우트의 자식 라우트
// Outlet === 자식 경로 요소
<Route index element={<Home />}>
  <Route path="teams" element={<Teams />}>
    <Route path=":teamId" element={<Team />} />
    <Route path="new" element={<NewTeamForm />} />
    <Route index element={<LeagueStandings />} />
  </Route>
</Route>


// 루트 경로 접근 시 렌더링
<App>
  <Home /> // 인덱스 라우트
</App>

// /teams 경로 접근 시 렌더링
<App>
  <Teams>
    <LeagueStandings /> // 인덱스 라우트
  </Teams>
</App>

// /teams/new 경로 접근 시 렌더링
<App>
  <Teams>
    <NewTeamForm />
  </Teams>
</App>

useNavigate

경로를 변경해 줌
navigate('/home') => localhost:3000/home
// localhost:3000/home
navigate('/home', { replace: true });

replace: true

해당 주소로 넘어간 후 뒤로 가기를 하더라도

방금의 페이지로 돌아오지 않고 메인 페이지 ('/') 로 돌아옴

 

replace: false

뒤로 가기 가능 (기본 값)


useParams

path 경로에 :style 문법을 사용했을 경우
useParams() 로 해당 값을 가져올 수 있음
import { Routes, Route, useParams } form 'react-router-dom';

function App() {
  return (
    <Routes>
      <Route
        path='products/:productId'
        element={<Product />}
      />
    </Routes>
  );
}

function Product() {
  // path 에서 params을 가져옴
  let params = useParams();
  // params 에서 이름으로 값을 찾음
  return <h1>Product {params.productId}</h1>;
}

useLocation

현재 URL 정보를 가져올 수 있음
useLocation Hooks는 현재 위치 객체를 반환함
const location = useLocation();

console.log(location);
// { 
//   pathname: 'products/food/', 
//   search: '?fruits', 
//   hash: '', 
//   state: undefined
// }

useRoutes

<Routes> 와 기능적으로 동일함
<Route> 요소 대신 JavaScript 객체를 사용해 경로를 정의함
이 객체는 <Route> 요소와 동일한 속성을 갖지만 JSX가 필요하지 않음
import * as React from 'react';
import { useRoutes } from 'react-router-dom';

function App() {
  let element = useRoutes([
    {
      path: '/',
      element: <DashBoard />,
      children: [
        {
          path: 'messages',
          element: <DashBoardMessage />
        },
        { path: 'tasks', element: <DashBoardTasks /> }
      ]
    },
    { path: 'team', element: <AboutPage /> }
  ]);
  
  return element;
}

Link 구성 요소

to 속성을 이용해 이동할 경로를 지정
링크 클릭 시 해당 경로 이름과 매치되는 구성 요소를 렌더링함
<Link to='about'>About 페이지 보여주기</Link>