간단한 사이트를 하나 구현해보면서 필요한 기능을 찾아 학습하는 게 좋을 것 같아 냅다 튜토리얼 이후 새 프로젝트를 시작해봤다. 일단 사이트이니 라우팅 기능이 필요했는데, 어째서인지 구글링 결과 2019년과 2021년의 React Route 코드가 다르고 내 코드에서는 에러만 잔뜩 뱉거나 아무 에러 없이 화면이 렌더링되지 않아 텅 비어버리는 게 아니겠는가?!
그래서 결국 쉬운 길을 가려다 길을 잃었다.
영어에 눈이 조금 흐려지는 것 같지만 공식 문서로 왔다.
react-router-dom
설치한다.npm i react-router-dom
당연한 것이지만 예제 코드를 읽으면서 쓰고 나서 npm start
했다가 모듈 못 찾았다는 콘솔 에러를 보고 호다닥 설치 해주었다. react-dom
과 달리 create-react-app
으로 프로젝트를 생성했을 때 node_modules
에 설치되는 기본 모듈이 아닌가보다.
<Router>
안에 <Routes>
, 그 안에 각 필요한 <Route>
를 작성한다.import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
function MainRouter(props) {
return (
<Router>
<Routes>
<Route
path="/main"
element={<Example />} />
</Routes>
</Router>
);
}
<Switch>
라는 것으로 래핑한 코드를 봤는데 그건 4인지 5인지 모르겠으나 현재(v6)에는 'react-router-dom'에서 import도 안 되는 것이었다. <Route>
의 element
로는 함수형 컴포넌트의 return()
에 들어갈 렌더링될 jsx를 넣어주면 된다.
useParams
를 이용하면 URI의 parameter를 읽어 사용 가능하다.import { BrowserRouter as Router, Routes, Route, useParams } from 'react-router-dom';
function MainRouter(props) {
return (
<Router>
<Routes>
<Route
path="/:param1"
element={<Example />} />
</Routes>
</Router>
);
}
function Example(props) {
const { param1 } = useParams();
return (
<div>param: {param1}</div>
)
}
errorElement
를 이용하여 페이지 에러 핸들링을 할 수 있다.공식 문서에 "(!) DANGER: This feature only works if using a data router like createBrowserRouter" 라는 문장이 함께 작성되어 있고 실제로 이 생성 코드를 넣어주지 않았더니 동작하지 않고 있다. create-browser-router
를 함께 사용해야만 동작하는 것으로 이해가 된다.
index.js
에서 <RouterProvider />
를 이용하여 create-browser-router
로 생성한 라우터를 root element에 넣어주었다.
https://reactrouter.com/en/main/route/error-element
https://reactrouter.com/en/main/routers/create-browser-router
출처는 React Router, Picking a Router
(v6.4) 기준 세 가지 종류의 라우터가 있다.
createBrowserRouter
createMemoryRouter
createHashRouter
createBrowserRouter
를 추천한다.createHashRouter
를 추천한다?createMemoryRouter
를 사용하는 것이 가장 쉬울 것이다. (DOM History API를 요구하는 사이트에 사용된 라우터와 다르게?)This is the recommended router for all React Router web projects. It uses the DOM History API to update the URL and manage the history stack.
import { createRoot } from 'react-dom/client';
import {
createBrowserRouter,
RouterProvider
} from 'react-router-dom';
import { Main } from './pages/main.js';
import { Sub1 } from './pages/sub1.js';
import { Sub2 } from './pages/sub2.js';
import { ErrorPage } from './pages/error.js';
const router = createBrowserRouter([
{
path: '/',
element: <Main />,
errorElement: <ErrorPage />,
children: [
{
path: '/sub1',
element: <Sub1 />,
},
{
path: '/sub2',
element: <Sub2 />,
},
// ...
]
}
]);
const root = createRoot(document.getElementById('root'));
root.render(<RouterProvider router={router} />);
routes
route
object의 배열.route
object는 children
property로 route
배열을 가질 수 있다.