こんにちは、サイオステクノロジーの遠藤です。
今回は、WebフレームワークであるRemixとルーティングライブラリであるReact Routerが統合されたReact Router v7のルーティングについてまとめていきます。
ルーティング方法
React Router v7では、Configuring Routes、Component Routes、File Route Conventionsの3種類のルーティング方法があります。
Configuring Routes
React Router v7のデフォルトで設定されるルーティングで、app/routes.tsに定義されたルーティング構成が反映されます。
Component Routes
以下のコードのような形で定義するルーティング方法。React Router v6で使用されていた定義らしく、v6から変更なく使用できるのが利点のよう。
ただ、Remixと統合されたことによって使用可能になった in data loading, actions, code splitting といった機能が使用できないのは注意ポイントです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import { Routes, Route } from "react-router"; function Wizard() { return ( <div> <h1>Some Wizard with Steps</h1> <Routes> <Route index element={<StepOne />} /> <Route path="step-2" element={<StepTwo />} /> <Route path="step-3" element={<StepThree />} /> </Routes> </div> ); } |
File Route Conventions
Next.jsのPages Router のようなファイルベースでのルーティングをapp/routes以下のファイルに対して行える機能。ただ、「.」を利用してファイルを決定するらしく、ネストが深くなっていった場合に大変そうという印象を受けました。
ファイル構成
1 2 3 4 5 6 7 8 | app/ ├── routes/ │ ├── _index.tsx │ ├── about.tsx │ ├── concerts.trending.tsx │ ├── concerts.salt-lake-city.tsx │ └── concerts.san-diego.tsx └── root.tsx |
URLとファイルの対応
URL | Matched Route |
---|---|
/ | app/routes/_index.tsx |
/about | app/routes/about.tsx |
/concerts/trending | app/routes/concerts.trending.tsx |
/concerts/salt-lake-city | app/routes/concerts.salt-lake-city.tsx |
/concerts/san-diego | app/routes/concerts.san-diego.tsx |
今回はConfiguring Routesの書き方についてご紹介します。
Configuring Routesの書き方
Routesの基本
ルートは app/routes.ts
に定義され、URLパターンとルートモジュールのファイルパスが必要です。
1 2 3 4 5 | import { type RouteConfig, route } from "@react-router/dev/routes"; export default [ route("some/path", "./some/file.tsx"), ] satisfies RouteConfig; |
Routesの設定例
例えば、以下のようにルートを設定できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import { type RouteConfig, route, index, layout, prefix } from "@react-router/dev/routes"; export default [ index("./home.tsx"), route("about", "./about.tsx"), layout("./auth/layout.tsx", [ route("login", "./auth/login.tsx"), route("register", "./auth/register.tsx"), ]), ...prefix("concerts", [ index("./concerts/home.tsx"), route(":city", "./concerts/city.tsx"), route("trending", "./concerts/trending.tsx"), ]), ] satisfies RouteConfig; |
このように、レイアウトルートや動的セグメントを含むルートも定義できます。
ルートモジュールとは?
各ルートに対応するファイル(ルートモジュール)は、実際のページのコンポーネントやデータフェッチのロジックを定義します。
1 2 3 4 5 6 7 8 9 10 | import type { Route } from "./+types/team"; export async function loader({ params }: Route.LoaderArgs) { let team = await fetchTeam(params.teamId); return { name: team.name }; } export default function Component({ loaderData }: Route.ComponentProps) { return <h1>{loaderData.name}</h1>; } |
ルートモジュールには、アクション、ヘッダー、エラー境界などの機能があり、上の例はloader
を使用してページのデータ取得をルートレベルで管理している様子です。
ルートの種類と使いどころ
1. ネストされたルート
ルートをネストして階層構造を作ることができます。
1 2 3 4 5 6 | export default [ route("dashboard", "./dashboard.tsx", [ index("./home.tsx"), route("settings", "./settings.tsx"), ]), ] satisfies RouteConfig; |
/dashboard
の中に /dashboard/settings
という子ルートを作成できます。
2. レイアウトルート
layout
を使うと、URLを変えずに共通のレイアウトを適用できます。
1 2 3 4 5 6 | export default [ layout("./marketing/layout.tsx", [ index("./marketing/home.tsx"), route("contact", "./marketing/contact.tsx"), ]), ] satisfies RouteConfig; |
動的セグメントとパラメータ
URLの一部を動的に受け取る場合は、:paramName
の形式を使います。
1 | route("teams/:teamId", "./team.tsx"), |
取得したパラメータは params
から利用できます。
1 2 3 | export default function Component({ params }: Route.ComponentProps) { return <h1>Team ID: {params.teamId}</h1>; } |
File Route Conventionsと組み合わせる
以下のような形で、File Route ConventionsとConfiguring Routesを組み合わせることが可能です。そのため、普段はFile Route Conventionsで管理を行い、複雑なルーティング制御が必要な場合にはConfiguring Routesを利用するといったことも可能です。
1 2 3 4 5 6 7 8 9 10 11 | import { type RouteConfig, route, } from "@react-router/dev/routes"; import { flatRoutes } from "@react-router/fs-routes"; export default [ route("/", "./home.tsx"), ...(await flatRoutes()), ] satisfies RouteConfig; |
まとめ
今回は、React Router v7のルーティング方法の一つであるConfiguring Routesについてまとめました。React Router v7を利用したのが今回が初めてだったため、最初はドキュメントを読んでも「?」状態でしたが、ルーティング方法が3つあるということを知ってからはだいぶ理解を進めることが出来ました。
React Router v7は、 Remix の特徴を受け継ぎ Web 標準に沿っているということで、基本を身につけるためにもしばらく触ってみようと思います。
ではまた~