(React) React-Router-Dom V6 업그레이드


반드시 공식 문서를 읽어보실 것을 권장드립니다!
공식문서 보기


주요 변화 요약

  • Switch 대신 Router로 변경

  • 중첩 라우터에서 Outlet 컴포넌트를 사용해서 구현할 수 있다.

  • useLocation : pathname을 가져와서 styled-components와 결합할 수 있다.

  • useRoutes Hook을 통해 child의 child도 정의할 수 있다. (기존에는 react-route-config을 별도로 설치해야 가능했음)

  • useHistory 대신 useNavigate로 이름이 변경되었다.


Switch 대신 Routes 사용하기

Switch가 Routes로 변경되었다.
Components를 불러오는 방식도 변경되었는데, 에로우 펑션을 활용해 컴포넌트를 전달하던 방식에서 element로 바로 component를 전달한다.

예제보기

// v5까지의 방식 

function App() {
  return (
    <BrowserRouter>
      <Switch>
        <Route path="/" component={() => <Home />} />
        <Route exact path="/write" component={() => <Write />} />
        <Route component={() => <div>Page Not Found</div>} />
      </Switch>
    </BrowserRouter>
  );
}

// v6방식 
const Router = () => {
  return (
    <BrowserRouter>
      <Header />
      <Routes>
        <Route path="/" element={<Main />} />
        <Route path="/page1/*" element={<Page1 />} />
        <Route path="/page2/*" element={<Page2 />} />
        <Route path="/*" element={<NotFound />} />
      </Routes>
    </BrowserRouter>
  );
};

중첩 라우팅

App.js에서 중첩 라우터를 사용하고, 중첩 라우터에서 Outlet 컴포넌트를 사용가능하다.

App.js에서 자식 태그로 중첩하는 라우터를 기재하고, Web.js에서 Outlet 라이브러리를 통해 가져온다.

// App.js
const App = () => {
  return (
    <BrowserRouter>
      <Header />
      <Routes>
        <Route path="/" element={<Main />} />
        <Route path="/page1/*" element={<Page1 />} />
        <Route path="/page2/*" element={<Page2 />} />
        <Route path="/*" element={<NotFound />} />
      </Routes>
    </BrowserRouter>
  );
};

// Web.js
import { Link, Routes, Route, Outlet } from "react-router-dom";

const Web = () => {
  return (
    <div>
      <h1>This is Web</h1>
      <ul>
        <li>
          <Link to="1">Post #1</Link>
        </li>
        <li>
          <Link to="2">Post #2</Link>
        </li>
        <li>
          <Link to="3">Post #3</Link>
        </li>
        <li>
          <Link to="4">Post #4</Link>
        </li>
      </ul>
      <Outlet />
    </div>
  );
};

export default Web;

useLocatio

pathname을 가져와 styled-components와 결합하기

import React from "react";
import { Link, useLocation } from "react-router-dom";
import styled from "styled-components";

const HeaderWrapper = styled("header")`
  margin-bottom: 30px;
`;
const List = styled("ul")`
  display: flex;
`;
const Item = styled("li")`
  margin-right: 20px;
  text-transform: uppercase;
  font-weight: 600;
  color: ${(props) => (props.selected ? "white" : "black")};
  background-color: ${(props) => (props.selected ? "#f1c40f" : "white")};
`;

const Header = () => {
  const { pathname } = useLocation();
  return (
    <HeaderWrapper>
      {/* header 태그 */}
      <List>
        {/* ul 태그 */}
        <Item selected={pathname.startsWith("/web")}>
          {/* li 태그 */}
          <Link to="/web">Go to Web</Link>
        </Item>
        <Item selected={pathname === "/design"}>
          <Link to="/design">Go to Design</Link>
        </Item>
        <Item selected={pathname === "/server"}>
          <Link to="/server">Go to Server</Link>
        </Item>
      </List>
    </HeaderWrapper>
  );
};
export default Header;

useRoutes

child의 child까지 자식 컴포넌트들을 랜더링하기 위해
react-router-config를 별도로 설치해 사용했다면 이제는 useRoutes Hook을 사용해 구성할 수 있다.

function App() {
  let element = useRoutes([
	// Route에서 사용하는 props의 요소들과 동일
    { path: "/", element: <Home /> },
    { path: "dashboard", element: <Dashboard /> },
    {
      path: "invoices",
      element: <Invoices />,
	 // 중첩 라우트의 경우도 Route에서와 같이 children이라는 property를 사용
      children: [
        { path: ":id", element: <Invoice /> },
        { path: "sent", element: <SentInvoices /> }
      ]
    },
	// NotFound 페이지는 다음과 같이 구현할 수 있음
    { path: "*", element: <NotFound /> }
  ]);
	// element를 return함으로써 적절한 계층으로 구성된 element가 렌더링 될 수 있도록 함
  return element;
}

< Routes>는 useRoutes를 감싼 wrapper라고 공식문서라고 언급하는데, 공식문에서는 이 둘 모두를 권장한다.


useHisroty 대신 useNavigate

v6부터는 navigate라는 명칠을 사용한다. history.push와 history.replace 모두 navigate라는 명칭으로 사용한다.

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

function App() {
  let navigate = useNavigate();
  function handleClick() {
    navigate("/home");
  }
  return (
    <div>
      <button onClick={handleClick}>go home</button>
    </div>
  );
}

출처

[react-router-dom v6 (Upgrading from v5)

출처: https://snupi.tistory.com/174 [SNUPI]

좋은 웹페이지 즐겨찾기