React Router v6のルーティング学習

## はじめに
ゆかっしゅです。
2021年に事務職からデザイナー/コーダーにジョブチェンジをし、現在はフロントエンドエンジニアにスキルアップするべく、モダンフロントエンドを学習しています。

今回はReact Router v6を学習したので備忘録として記事を書きます。
普段はNext.js使っていてReact Routerあまり使っていなかったので、いい学習になりました。

また、v5からv6の変更点まだよくわかってないよって方も見ていただければ幸いです。

![スクリーンショット 2025-04-23 180554.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4068307/a0535fb6-b90e-499e-8378-562fff028f37.png)


## 利用技術
- React(19.1.0)
- Java Script
- react-router-dom(7.5.1)
- Vite(6.3.2) ※stackblitzを使用

## 環境構築
下記コマンドでインストールする。
※お使いのパッケージマネージャーに置き換えてインストールしてください。
```
pnpm add react-router-dom
```

## 基本構造
```javascript:App.jsx

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
```javascript:Page1.jsx
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ディレクトリにルート設定を分ける

```javascript:Router.jsx
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()でルートを整理する

```javascript:Router.jsx

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とか使うようになる時もあると思うので、しっかり使い方を覚えておきたいです。