React Router v7のルーティング方法 Configuring Routes を整理する

こんにちは、サイオステクノロジーの遠藤です。

今回は、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 といった機能が使用できないのは注意ポイントです。

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以下のファイルに対して行える機能。ただ、「.」を利用してファイルを決定するらしく、ネストが深くなっていった場合に大変そうという印象を受けました。

ファイル構成

 app/
├── routes/
│   ├── _index.tsx
│   ├── about.tsx
│   ├── concerts.trending.tsx
│   ├── concerts.salt-lake-city.tsx
│   └── concerts.san-diego.tsx
└── root.tsx

URLとファイルの対応

URLMatched Route
/app/routes/_index.tsx
/aboutapp/routes/about.tsx
/concerts/trendingapp/routes/concerts.trending.tsx
/concerts/salt-lake-cityapp/routes/concerts.salt-lake-city.tsx
/concerts/san-diegoapp/routes/concerts.san-diego.tsx

今回はConfiguring Routesの書き方についてご紹介します。

Configuring Routesの書き方

Routesの基本

ルートは app/routes.ts に定義され、URLパターンルートモジュールのファイルパスが必要です。

import { type RouteConfig, route } from "@react-router/dev/routes";

export default [
  route("some/path", "./some/file.tsx"),
] satisfies RouteConfig;


Routesの設定例

例えば、以下のようにルートを設定できます。

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;


このように、レイアウトルートや動的セグメントを含むルートも定義できます。

ルートモジュールとは?

各ルートに対応するファイル(ルートモジュール)は、実際のページのコンポーネントやデータフェッチのロジックを定義します。

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. ネストされたルート

ルートをネストして階層構造を作ることができます。

export default [
  route("dashboard", "./dashboard.tsx", [
    index("./home.tsx"),
    route("settings", "./settings.tsx"),
  ]),
] satisfies RouteConfig;

/dashboard の中に /dashboard/settings という子ルートを作成できます。

2. レイアウトルート

layout を使うと、URLを変えずに共通のレイアウトを適用できます。

export default [
  layout("./marketing/layout.tsx", [
    index("./marketing/home.tsx"),
    route("contact", "./marketing/contact.tsx"),
  ]),
] satisfies RouteConfig;


動的セグメントとパラメータ

URLの一部を動的に受け取る場合は、:paramName の形式を使います。

route("teams/:teamId", "./team.tsx"),

取得したパラメータは params から利用できます。

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を利用するといったことも可能です。

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 標準に沿っているということで、基本を身につけるためにもしばらく触ってみようと思います。

ではまた~

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です