🛣
react-router v6.4 で比較的型安全なルーティングを実現することで管理を楽にする
はじめに
react-router が v6.4 で比較的型安全なルーティングができるようになった?のでメモとして残しておきます。
以下のように作成することで、パス管理やルーティングの処理、遷移などが楽になります。
ファイル構成
今回関係のあるファイルは 📝 がついているものです。
vite で作成したアプリです。
yarn create vite {app_name} --template react-ts
.
├── index.html
├── package.json
├── public
│ └── vite.svg
├── src
│ ├── App.css
│ ├── App.tsx #📝
│ ├── assets
│ │ └── react.svg
│ ├── index.css
│ ├── main.tsx
│ ├── pages
│ │ ├── top
│ │ │ └── index.tsx #📝
│ │ └── users
│ │ └── [id]
│ │ └── index.tsx #📝
│ └── vite-env.d.ts
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── yarn.lock
react-router-dom をインストール
yarn add react-router-dom
実装例
src/App.tsx
import { BrowserRouter, ParamParseKey, Route, Routes, useParams } from "react-router-dom";
import User from "./pages/users/[id]";
import "./App.css";
import Top from "./pages/top";
export const PATHS = {
TOP: "/",
ABOUT: "/about",
USERS_ID: "/users/:id",
} as const;
// これでクエリパラメータの id が取り出せる
export const useParamsUsersId = useParams<ParamParseKey<typeof PATHS.USERS_ID>>;
function App() {
return (
<BrowserRouter>
<Routes>
<Route path={PATHS.TOP} element={<Top />} />
<Route path={PATHS.ABOUT} element={<div>About</div>} />
<Route path={PATHS.USERS_ID} element={<User />} />
<Route path="*" element={<div>Not Found</div>} />
</Routes>
</BrowserRouter>
);
}
export default App;
src/pages/top/index.tsx
import { generatePath } from "react-router-dom";
import { PATHS } from "../../App";
function Top() {
return (
<div>
<h1>Top</h1>
{/* generatePath で :id に代入できる */}
<a href={generatePath(PATHS.USERS_ID, { id: "1" })}>User 1</a>
<br />
{/* これはエラー */}
{/* Argument of type '{ userId: string; }' is not assignable to parameter of type '{ id: string; }'.
Object literal may only specify known properties, and 'userId' does not exist in type '{ id: string; }' */}
<a href={generatePath(PATHS.USERS_ID, { userId: "2" })}>User 2</a>
<br />
<a href={generatePath(PATHS.USERS_ID, { id: "3" })}>User 3</a>
</div>
);
}
export default Top;
src/pages/users/[id]/index.tsx
import { useParamsUsersId } from "../../../App";
function User() {
const { id } = useParamsUsersId();
return (
<div>
<h1>User</h1>
<p>id: {id}</p>
</div>
);
}
export default User;
おわりに
これでルーティングの変更容易性が少しは上がりそうです 💪
Discussion