はじめに
ゆかっしゅです。
2021年に事務職からデザイナー/コーダーにジョブチェンジをし、現在はフロントエンドエンジニアにスキルアップするべく、モダンフロントエンドを学習しています。
今回はReact Router v6を学習したので備忘録として記事を書きます。
普段はNext.js使っていてReact Routerあまり使っていなかったので、いい学習になりました。
また、v5からv6の変更点まだよくわかってないよって方も見ていただければ幸いです。
利用技術
- React(19.1.0)
- Java Script
- react-router-dom(7.5.1)
- Vite(6.3.2) ※stackblitzを使用
環境構築
下記コマンドでインストールする。
※お使いのパッケージマネージャーに置き換えてインストールしてください。
pnpm add react-router-dom
基本構造
import { BrowserRouter, Link, Routes, Route } from 'react-router-dom';
import { Home } from './Home';
import { Page1 } from './Page1';
import { Page2 } from './Page2';
import { Page1DetailA } from './Page1DetailA';
import { Page1DetailB } from './Page1DetailB';
function App() {
return (
<BrowserRouter>
<div>
<Link to="/">Home</Link>
<br />
<Link to="/page1">Page1 </Link>
<br />
<Link to="/page2">Page2 </Link>
</div>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/page1" element={<Page1 />}>
<Route path="detaila" element={<Page1DetailA />} />
<Route path="detailb" element={<Page1DetailB />} />
</Route>
<Route path="/page2" element={<Page2 />} />
</Routes>
</BrowserRouter>
);
}
export default App;
BrowserRouter
ルートの設定をする際、一番外側に置く。BrowserRouter
の子要素にLink
やRoute
を置いてルートを指定する。
ChatGpt君が言うにはこのBrowserRouter
はAppフォルダに一回だけ記載する。
(子コンポーネントでBrowserRouter
を記載するとエラーになる)
Link
テキストリンク等の部分をLink
で囲む。<a>
に似ている。
Link
にはto
属性を指定でき、そこにパスを記載する。
Routes
Route
を囲む。
Route
ルートの設定を記載する。path
属性とelement
属性をしてでき、path
属性で指定したパスの時、element
属性で指定したコンポーネントを表示するという書き方。一つのパスに一つ必要。
忘れがちなOutlet
import { Link, Outlet, useNavigate } from 'react-router-dom';
export const Page1 = () => {
const arr = [...Array(100).keys()];
const navigate = useNavigate();
const goToDetailA = () => {
navigate('/page1/detaila');
};
return (
<div>
<h1>Page1ページです</h1>
<Link to="/page1/detaila" state={arr}>
DetailA
</Link>
<br />
<Link to="/page1/detailb">DetailB</Link>
<br />
<button onClick={goToDetailA}>DetailA</button>
<Outlet />
</div>
);
};
Outlet
Link
で記載したテキストリンク達、ルートの設定もばっちりなのにリンク押してもDetailAやDetailBのページが表示されない!!ってなった時、50%位の確立でOutlet
の記載漏れな気がする。このOutlet
を置いた場所に子ルートが表示される。
useNavigate
テキストリンクなどのルート設定はLink
を使用しているが、ボタン・イベント・条件分岐付き遷移などのJavaScriptでルートを設定したいときは、このuseNavigate
を使用する。
const navigate = useNavigate();
const goToDetailA = () => {
navigate('/page1/detaila');
};
button
タグのOnClick
にgoToDetailA
関数を指定して、goToDetailA
の中身をこのように記載する。navigateでパスを指定する。パスのほかにもnavigate(-1)
で1つ前のページに戻るなどの記載もできる。
補足 Routerディレクトリにルート設定を分ける
import { Routes, Route } from 'react-router-dom';
import { Home } from '../Home';
import { Page1 } from '../Page1';
import { Page2 } from '../Page2';
import { Page1DetailA } from '../Page1DetailA';
import { Page1DetailB } from '../Page1DetailB';
export const Router = () => {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/page1" element={<Page1 />}>
<Route path="detaila" element={<Page1DetailA />} />
<Route path="detailb" element={<Page1DetailB />} />
</Route>
<Route path="/page2" element={<Page2 />} />
</Routes>
);
};
ルート部分を書き出すとルートが増えてもAppがごちゃごちゃならないので個人的には好き。
補足 map()でルートを整理する
import { Routes, Route } from 'react-router-dom';
import { Home } from '../Home';
import { Page1 } from '../Page1';
import { Page2 } from '../Page2';
import { Page1DetailA } from '../Page1DetailA';
import { Page1DetailB } from '../Page1DetailB';
import { UrlParameter } from '../Urlparameter';
import { Page404 } from '../Page404';
const routes = [
{ path: '/', element: <Home /> },
{
path: '/page1',
element: <Page1 />,
children: [
{ path: 'detaila', element: <Page1DetailA /> },
{ path: 'detailb', element: <Page1DetailB /> },
],
},
{
path: '/page2',
element: <Page2 />,
children: [{ path: ':id', element: <UrlParameter /> }],
},
{ path: '*', element: <Page404 /> },
];
export const Router = () => {
const renderRoutes = (routesArray) =>
routesArray.map(({ path, element, children }) => (
<Route key={path} path={path} element={element}>
{children && renderRoutes(children)}
</Route>
));
return <Routes>{renderRoutes(routes)}</Routes>;
};
ルートが増えたときにいちいちRoute
書かなくてもいいし、パスはパスでまとまっていたほうが個人的には好き。
おわりに
普段はnext.jsを使っていますが、今後Viteとか使うようになる時もあると思うので、しっかり使い方を覚えておきたいです。