React-Router v6を触ってみた

こちらの記事で一部動作が確認できなかった部分があったので、React-Routerのv6を使ってv5からの変更点を確認しつつ、動作確認できなかった部分を確認してみた。
## v6での変更点
`Route`周りの記述が`Routes`タグの中に`Route`タグを使ってルーティングを定義するようになっている様子。
表示内容は`element`に指定する。

また、`useHistory`の代わりに`useNavigate`を利用するようになった。
「戻る」は引数に`-1`を渡す。

:::note info
2024/10/20 追記
stateを遷移先に渡したい場合は以下のように記述する。
```
navigate('/users', { state: { isAdmin: false } })
```
:::
### 環境
```
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.15.0"
```

### 確認
確認した際のソースコードを記載する。
```jsx
<BrowserRouter>
  <div>
    <Routes>
      <Route exact path="/" element={<Top />} />
      <Route exact path="/Page" element={<Page />} />
      <Route exact path="/Page/:id" element={<Page />} />
      <Route exact path="/Page/query?value=123" element={<Page />} />
      <Route exact path="/Page/Detail" element={<PageDetail />} />
      <Route exact path="*" element={<Page404 />} />
    </Routes>
  </div>
</BrowserRouter>
```

App.jsx
```jsx
import { BrowserRouter, Link, Route, Routes } from 'react-router-dom';
import './App.css';
import { Page } from './Page';
import { PageDetail } from './PageDetail';
import { Top } from './Top';
import { Page404 } from './Page404';

function App() {
  return (
    <BrowserRouter>
      <div>
        <Routes>
          <Route exact path="/" element={<Top />} />
          <Route exact path="/Page" element={<Page />} />
          <Route exact path="/Page/:id" element={<Page />} />
          <Route exact path="/Page/query?value=123" element={<Page />} />
          <Route exact path="/Page/Detail" element={<PageDetail />} />
          <Route exact path="*" element={<Page404 />} />
        </Routes>
      </div>
    </BrowserRouter>
  );
}

export default App;
```

Top.jsx
```jsx
import { Link, useNavigate } from 'react-router-dom';

export const Top = () => {
  const navigate = useNavigate();
  return (
    <>
      <h1>Top</h1>
      <button onClick={() => navigate('/Page')}>Page</button>
      <br />
      <Link to="/Page/100">URLParameter</Link>
      <br />
      <Link to="/Page/query?value=123">Queryparameter</Link>
    </>
  );
};
```

Page.jsx
```jsx
import { Link, useLocation, useParams } from 'react-router-dom';
import { PageDetail } from './PageDetail';

export const Page = () => {
  const { id } = useParams();
  const { search } = useLocation();
  const query = new URLSearchParams(search);

  return (
    <div>
      <h1>Page</h1>
      <Link to="/Page/Detail" state={{ a: 1, b: 2 }} element={PageDetail}>
        Detail
      </Link>
      <p>URL Parameter: {id}</p>
      <p>Query Parameter: {query.get('value')}</p>
    </div>
  );
};
```

PageDetail.jsx
```jsx
import { useLocation } from 'react-router-dom';

export const PageDetail = () => {
  const { state } = useLocation();

  return (
    <>
      <h1>PageDetail</h1>
      <p>{`state: a: ${state.a}, b: ${state.b}`}</p>
    </>
  );
};
```

Page404.jsx
```jsx
import { useNavigate } from 'react-router-dom';

export const Page404 = () => {
  const navigate = useNavigate();
  return (
    <>
      <h1>Page Not Found</h1>
      <button onClick={() => navigate(-1)}>戻る</button>
    </>
  );
};
```

### 参考

https://qiita.com/TaikiTkwkbysh/items/f0b8f6a710b7f4f832c1

https://qiita.com/kon_125/items/d9c89ebae03bf8cfd251