React Router v6 정리

Maria Kim·2021년 11월 18일
8

이번 업데이트로 정말 많이 똑똑해지고 편리해진 React Router v6!

React Router v6 업데이트가 이전과 달라진 부분들이 많아 정리해 보려 한다. 아래의 정리는 모두 2021.11.18 의 React Router 공식 문서를 참고해 정리한 내용이다.

언제나 정확하고 최신의 자료는 공식 문서에서 참고하기!
[React Router 공식문서]

React Router 설치
npm i react-router

React Router v6 정리

가장 일치하는 route로 알아서 매칭시킨다

이전에는 아주 정확하게 경로를 path 작성하지 않거나 모호한 경우 문제가 생겼다. 하지만 이번 업데이트로 가장 알맞는 부분으로 알아서 찾아간다. exact 도 그래서 사라졌다.

<Route path="posts/:postId" element={<Team />} />
<Route path="posts/new" element={<NewTeamForm />} />

위 예시 코드에서 보면 posts/new 는 위 2개의 route에 모두 일치한다. 하지만 posts/new가 더 구체적이기 때문에 이 <NewTeamForm /> 가 보일 것이다.

Link 는 이전처럼 태그에 바로 route 주소를 설정해 옮길 때 사용하면 된다.

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

function App() {
  return (
    <div>
      <h1>Home</h1>
      <nav>
        <Link to="/">Home</Link>
        <Link to="contact">Contact</Link>
      </nav>
    </div>
  );
}

useNavigate

이전 버전에서는 useHistory 가 있었는데 이제는 useNavigate를 써야 한다.

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

function Invoices({checkValidation}) {
  let navigate = useNavigate();
  const checkLogin = () => {
    if(checkValidation){
      navigate(`/main`)
    }
  }
  return (
  
  	...
  
    <div>
      <LoginBtn onClick={checkLogin}/>
    </div>
  );
}

URL 파라미터 읽어오기

import { Routes, Route, useParams } from "react-router-dom";

function App() {
  return (
    <Routes>
      <Route
        path="posts/:postId"
        element={<Post />}
      />
    </Routes>
  );
}

function Post() {
  let params = useParams();
  return <h1>Post {params.postId}</h1>;
}
  • :style syntax 를 route path 에 사용하면 useParams() 로 이를 불러와 사용할 수 있다.

  • : 뒤에 나오는 부분이 paramskey 부분이 되어 :postIdpostIdkey가 되어 불러오고 있음을 확인하자.

  • 이렇게 가져온 id로 fetch data를 하는데 가장 많이 사용한다.

function Invoice() {
  let { postId } = useParams();
  let post = useFakeFetch(`/api/invoices/${postId}`);
  return post ? (
    <div>
      <h1>{post.postTitle}</h1>
    </div>
  ) : (
    <Loading />
  );
}

Nested Routes

react router 에서 가장 강력한 기능 중 하나라고 말하는 nested routes (복잡한 layout code 안에서 고민하지 않게 해주는 아주 고마운 기능)

  • route 들은 다른 route 안에 nest(감싸질 수 있다) 될 수 있다.
  • 자식 route의 path 는 부모의 path 뒤에 붙어 사용된다.
function App() {
  return (
    <Routes>
      <Route path="posts" element={<Posts />}>
        <Route path=":postId" element={<Post />} />
        <Route path="notice" element={<Notice />} />
      </Route>
    </Routes>
  );
}
  • 그렇기에 위 코드는 /posts, /posts/:postId, /posts/notice 3가지의 path 가 있다.
  • posts 으로 감싸진 notice route 는 결과적으로 /posts/notice 가 되는 것이다.
  • 그리고 주의해야할 점은 이 path는 자기 자신인 <Notice />만 보여지는 것이 아니라 아래처럼 그려진다.
<App>
  <Posts>
    <Notice />
  </Posts>
</App>
  • 그리고 부모의 route 에서는 꼭 <Outlet>를 넣어야 하는데, 이 <Outlet>에 매칭되는 자식 route 가 그려지기 때문이다.
import { Routes, Route, Outlet } from "react-router-dom";

function Posts() {
  return (
    <div>
      <h1>Posts</h1>
      <Outlet />
    </div>
  );
} 
  • 이를 통해 페이지 곳곳에서 편리하게 router 를 지정하고 사용할 수 있다.

Index Routes

  • Route 에 들어가는 index 라는 값은 default child routes 라고 생각하면 된다
  • 부모에 여러 개의 자식 route 있는 경우 부모 경로에서 + '/' 인 경우 설정
  • v6 부터는 네스팅이 되기 때문에 현재까지의 경로 + '/' 를 한 path 에 연결할 component 간편하게 설정하기 위해 나온 명령어 이다.
  • index route 는 모든 레벨에서 사용 가능하다
function App() {
  return (
    <Routes>
      <Route index element={<Home />} />
      <Route path="about" element={<About />}>
        <Route index element={<AboutHome />} />
        <Route
          path="location"
          element={<AboutLocation />}
        />
      </Route>
    </Routes>
  );
}
  • <Link to= 'path'> 의 path 에 들어가는 값은 그 route 를 렌더링 한 route에 영향을 받습니다.
    (path 가 '/' 로 시작하면 부모 route 의 path를 붙이지 않고 그 경로로 바로 감)
import {
  Routes,
  Route,
  Link,
  Outlet
} from "react-router-dom";

function Home() {
  return <h1>Home</h1>;
}

function About() {
  return (
    <div>
      <h1>About</h1>
      <nav>
        <Link to="/location">Location</Link>{" "}
        <Link to="contact">Contact</Link>
      </nav>
      <hr />
      <Outlet />
    </div>
  );
}

function Location() {
  return <h1>Location</h1>;
}

function Contact() {
  return <h1>Contact</h1>;
}

function App() {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="about" element={<About />}>
        <Route path="location" element={<Location />} />
        <Route path="contact" element={<Contact />} />
      </Route>
    </Routes>
  );
}
  • 위의 2개의 Link 는 <About/> 안에서 랜더링 되었기 때문에 /about/location/, /about/contact/ 로 링크 될 것입니다.

"NOT FOUND" Routes

  • 만약 어떤 route 에도 url 에 맞지 않을 때, path="*"를 사용해서 "not found" 라우트를 렌더링 할 수 있다.
  • 이 라우트는 가장 낮은 우선순위를 가지기 때문에 다른 라우트 들이 맞지 않을 때 선택된다.
function App() {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="About" element={<About />} />
      <Route path="*" element={<NotFound />} />
    </Routes>
  );
}

Multiple Sets of Routes

  • app 에 하나의 <Router>만 사용해야 하지만 <Routes> 는 많이 사용해도 된다.
  • <Routes>는 독립적으로 작동됩니다. 그리고 자신의 자식 route 를 렌더링 합니다.
function App() {
  return (
    <div>
      <Nav>
        <Routes>
          <Route path="/" element={<MainNav />} />
          <Route
            path="news"
            element={<News />}
          />
        </Routes>
      </Sidebar>

      <MainContent>
        <Routes>
          <Route path="/" element={<Home />}>
            <Route path="about" element={<About />} />
            <Route path="contact" element={<Contact />} />
          </Route>
          <Route path="menu" element={<Menu />}>
            <Route path="icecream" element={<Icecream />} />
            <Route path=" tea" element={<Tea />} />
          </Route>
          <Route path="*" element={<NotFound />} />
        </Routes>
      </MainContent>
    </div>
  );
}

Descendant Routes

  • <Routes>는 어디에서나 렌더링 할 수 있음
  • 그렇기 때문에 다른 컴포넌트에서도 사용할 수 있는데, 이 경우 이 컴포넌트를 렌더링하는 라우트의 path 에 자동적으로 빌드 될 것
  • 이럴 경우 부모 라우트의 path에 '*'를 꼭 사용해야 함
  • 그렇지 않으면 부모의 라우트는 그 url을 인식하지 못함
function App() {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="dashboard/*" element={<About />} />
    </Routes>
  );
}

function Dashboard() {
  return (
    <div>
      <p>Look, more routes!</p>
      <Routes>
        <Route path="/" element={<DashboardGraphs />} />
        <Route path="location" element={<Location />} />
      </Routes>
    </div>
  );
}

[veloport 유튜브] React Router v5 → v6 빠르게 훑어보기

profile
Frontend Developer, who has business in mind.

1개의 댓글

comment-user-thumbnail
2022년 9월 5일

좋은 글 감사합니다!

답글 달기