ReactRouterでネストされたページ遷移を実現する。

## はじめに
React学習で使っていた動画教材の`react-router-dom`のバージョンがv5だったので、手元環境のv6に対応出来るように調べながら`ReactRouter`でのページ遷移についての学習を進めていました。
その際にネストのあるページ遷移に困ったので備忘録として残します。

## 完成形
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3814555/422fc57b-a4cf-5b47-8cf0-7f827d17293e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3814555/f4e59d20-be6b-c032-11f6-2e78d6c3928e.png)

Home,Page1,Page2に遷移出来て、Page1の中で更にPage1DetailA,Page2DetailBに遷移できるようになっています。（つまり、***Page1が今回の主題***です）

## 結論
①ルーティング設定部分で`Route`***を入れ子にする***
②ネストを表示するコンポーネントで`Outlet`***を使用する***


## まずはネストのないページ遷移を作成してみる
とはいってもまずはネストのないページ遷移を作ってみましょう。

### App.jsxの作成
①ルーティング機能が利用できるように全体を`BrowserRouter`で囲む
②`Link`の作成(各リンクを押下すると`to`に記載のパスに飛びます)
③ルーティングについて記載した`Router`コンポーネントを配置する

```react:App.jsx
import { BrowserRouter, Link } from "react-router-dom";
import { Router } from "./router/Router";
import "./styles.css"; //大して書いていないので掲載していません

export default function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <Link to="/">Home</Link>
        <Link to="/page1">Page1</Link>
        <Link to="/page2">Page2</Link>
      </div>
      <Router />
    </BrowserRouter>
  );
}
```

### Rourterコンポーネントの作成
①`Routes`で全体を囲む(複数の`Route`をグループ化するためのコンポーネント)
②`Route`で「どの`path`がきたらどの`element`(コンポーネント)を表示するか」を指定する

```react:Router.jsx
import { Routes, Route } from "react-router-dom";
import { Home } from "../Home";
import { Page1 } from "../Page1";
import { Page2 } from "../Page2";

export const Router = () => {
  return (
    <Routes>
      <Route path="/" element={<Home />}></Route>
      <Route path="/page1" element={<Page1 />}></Route>
      <Route path="/page2" element={<Page2 />}></Route>
    </Routes>
  );
};   
```
ネストのないページ遷移ではシンプルに`Route`を並列に記載してあげれば問題ありません。

## ネストがあるページ遷移を作成する
それではPage1内部で更にページ遷移を行ってみましょう。

ネストがあるページでやることは最初に述べましたが2つです。
①ルーティング設定部分で`Route`***を入れ子にする***
※今回であればPage1コンポーネント内部で更にページ遷移を行いたいので、このようになります
```diff_re_script:Router.jsx
import { Routes, Route } from "react-router-dom";
import { Home } from "../Home";
import { Page1 } from "../Page1";
+import { Page1DetailA } from "../Page1DetailA";
+import { Page1DetailB } from "../Page1DetailB";
import { Page2 } from "../Page2";

export const Router = () => {
  return (
    <Routes>
      <Route path="/" element={<Home />}></Route>
      <Route path="/page1" element={<Page1 />}>
+        <Route path="detailA" element={<Page1DetailA />}></Route>
+        <Route path="detailB" element={<Page1DetailB />}></Route>
      </Route>
      <Route path="/page2" element={<Page2 />}></Route>
    </Routes>
  );
};   
```
②ネストを表示するコンポーネントで`Outlet`***を使用する***

以下がPage1のリンクを押下して`/page1`へアクセスしたときに表示されるコンポーネントです。
ここで`Outlet`を使用してあげることで、その部分にネストされたコンポーネント(Page1DetailA,Page1DetailB)が表示されます。
```react:Page1.jsx
import { Outlet, useNavigate } from "react-router-dom";
export const Page1 = () => {
  const navigate = useNavigate(); //ここではボタン押下時のパスをLinkではなくuseNavigateで設定

  const handleClickA = () => {
    navigate("/page1/detailA");
  };

  const handleClickB = () => {
    navigate("/page1/detailB");
  };

  return (
    <div>
      <h1>Page1ページです</h1>
      <button onClick={handleClickA}>Page1DetailAへ</button>
      <button onClick={handleClickB}>Page1DetailBへ</button>
      <Outlet /> {/* 先ほど入れ子にしたRouteのelementがここに表示される */}
    </div>
  );
};
```

実際に、ボタン押下時にネストされたページが表示できています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3814555/f4e59d20-be6b-c032-11f6-2e78d6c3928e.png)

## おわり
備忘録でした。ありがとうございました～