[TIL] React Router Dom

대빵·2023년 11월 28일
1

React-Router 사용이유

그냥 a태그를 사용하면 페이지 전체가 새로로딩이 된다. 흔히 말해 화면이 깜빡임이 필수적으로 발생하고 이는 사용자 경험을 떨어뜨리는 큰 요인이다. 따라서, 라우팅을 통해 부드러운 화면전환을 위해 사용된다.

react-router-dom 설치

npm i react-router-dom
yarn add react-router-dom

세팅

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

BrowserRouter

history API를 활용해 history 객체를 생성한다.

history API는 내부적으로 stack 자료구조의 형태를 띄기 때문에 사용자가 방문한 url 기록들을 차곡차곡 쌓는 형태로 저장해둔다고 생각하면 된다.

라우팅을 진행할 컴포넌트 상위에 BrowserRouter 컴포넌트를 생성하고 감싸주어야 한다.

Route

현재 브라우저의 location(window.href.location 정보를 가져온다) 상태에 따라 다른 element를 렌더링한다.

Route.element: 조건이 맞을 때 렌더링할 element, <Element />의 형식으로 전달된다.

Route.path: 현재 path값이 url과 일치하는지 확인해 해당 url에 매칭된 element를 렌더링해준다.

Routes

모든 Route의 상위 경로에 존재해야 하며, location 변경 시 하위에 있는 모든 Route를 조회해 현재 location과 맞는 Route를 찾아준다!

const Router = () => {
  return (
    <BrowserRouter>
        <Routes>
          <Route path="/" element={<GalleryPage />} />
          <Route path="/gallery" element={<DetailCardPage />}>
            <Route path=":cardId" element={<DetailCard />} />
          </Route>
        </Routes>
    </BrowserRouter>
  );
};

Router 컴포넌트를 생성해준 뒤, 상위 렌더링 요소에 컴포넌트를 붙인다.

import Router from "./Router";

const App = () => (
  <>
      <Router />
  </>
);

export default App;

Link 컴포넌트는 라우터 내에서 직접적으로 페이지 이동을 하고자 할 때 사용되는 컴포넌트이다.

import React from 'react';
import {Link} from 'react-router-dom';

function Nav(){
  return (
    <div>
      <Link to='/'> Home </Link>
      <Link to='/about'> About </Link>
    </div>
  );
}

export default Nav;

위와 같은 방식으로 간단하게 to 속성에 경로를 넣어주는 방식으로 사용한다.

Relative

계층 구조에 상대적이다.
상대 경로 표현이 가능하므로, ./..와 같은 표현도 사용이 가능하다.

preventScrollReset

페이지 중간에 있는 컨텐츠 내부에서 tab 목록을 누르는 것과 같은 시도를 할 때, 기존의 Link 컴포넌트였다면 클릭 시 스크롤이 초기화되어 페이지 가장 위로 이동하게 된다.
그러나 이 속성을 true로 설정해주면 이를 방지할 수 있다!!

state

useLocation 훅과 연계하여 특정 state를 넘겨주는 것도 가능하다.

<Link to="new-path" state={{ some: "value" }} />

let { state } = useLocation();

Link는 a태그로 이루어져 있지만, 자체적으로 컴포넌트의 상태를 유지하거나, 화면 전체 리렌더링을 방지하는 등의 기능이 포함된 a 태그의 상위 버전이라고 생각하면 좋다.

useNavigate

useNavigate훅을 사용하면 특정 이벤트(onChange, onClick 등)가 발생했을 때 페이지 이동을 트리거할 수 있다.

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

const navigate = useNavigate();

const onClick = () => {
	navigate('/')
}

replace

기본값은 false이고, true로 설정한다면 이동 후 뒤로가기가 불가능해진다.

navigate("/", { replace: true });

state

Link와 마찬가지로 state를 전달이 가능하다.

navigate("/", { state: { cardId: cardId } });

const location = useLocation();
const { cardId } = location.state;

중첩 라우팅

V6에서 중첩 라우팅이 컴포넌트의 children과 같은 개념으로 중첨이 가능해져 더 직관적으로 변했다.
만약, /todotodo/:todoId 페이지가 있다고 한다면, 이전에는 각각 한 줄씩 차지하였는데, v6에서는 todo 라우트하위에 :todoId가 포함된 Route를 추가하면 중첩 라우팅이 된다.

하위에 있으면 자동적으로 /로 구분되기 때문에 추가적인 /를 path에 추가할 필요가 없어졌다.

<Routes>  
	<Route path="/todo">    
    	<Route path=":todoId" />
    </Route>
</Routes>

Outlet

특정 페이지들끼리 공통적으로 보여줘야 하는 레이아웃이 있을 때 유용하게 사용할 수 있다.
예를들어 Home, Detail, About페이지가 있다고 가정할 때 Detail, About페이지를 네비게이션으로 보여줘야 하는 상황일때 각 네비게이션 컴포넌트를 달아서 사용하지만, Outlet을 사용해서 한번에 호출해서 사용할 수 있다.

import { Outlet } from "react-router-dom"

export default function Layout() {
	return(
    	<>
        	<nav>navigation</nav>
            <Outlet />
        </>
    )
}

각 페이지 컴포넌트가 보여져야 하는 부분에 Outlet컴포넌트를 넣는다.

export default function App() {
	return(
    	<BrowserRouter>
        <Routes>
          <Route element={<Layout />}>
            <Route path="/detail" element={<Detail />} />
			<Route path="/about" element={<About />} />
          </Route>
          
          <Route path="/" element={<Home />} />
       	 </Routes>
    	</BrowserRouter>
    )
}

실행해보면 Layout안에 Outlet영역에 각 Route에 매칭시켜놓은 element들이 렌더링 되는 것을 볼 수 있다.

0개의 댓글