ルーティング
このページの内容

ルーティング

ルートの設定

ルートはapp/routes.tsで設定されます。各ルートには、URLと一致するURLパターンと、その動作を定義するルートモジュールへのファイルパスの2つの必須部分があります。

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

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

以下は、より大きなサンプルルート設定です。

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;

設定ではなくファイル命名規則によってルートを定義することを好む場合は、@react-router/fs-routesパッケージがファイルシステムルーティング規則を提供します。

ルートモジュール

routes.tsで参照されるファイルは、各ルートの動作を定義します。

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

ルートモジュールの例を以下に示します。

// provides type safety/inference
import type { Route } from "./+types/team";

// provides `loaderData` to the component
export async function loader({ params }: Route.LoaderArgs) {
  let team = await fetchTeam(params.teamId);
  return { name: team.name };
}

// renders after the loader is done
export default function Component({
  loaderData,
}: Route.ComponentProps) {
  return <h1>{loaderData.name}</h1>;
}

ルートモジュールには、アクション、ヘッダー、エラー境界などの機能が追加されていますが、これらについては次のガイドで説明します。ルートモジュール

ネストされたルート

ルートは親ルートの中にネストすることができます。

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

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

親のパスは子に自動的に含まれるため、この設定では"/dashboard""/dashboard/settings"の両方のURLが作成されます。

子ルートは、親ルートの<Outlet/>を通してレンダリングされます。

import { Outlet } from "react-router";

export default function Dashboard() {
  return (
    <div>
      <h1>Dashboard</h1>
      {/* will either be home.tsx or settings.tsx */}
      <Outlet />
    </div>
  );
}

ルートルート

routes.ts内のすべてのルートは、特別なapp/root.tsxモジュール内にネストされています。

レイアウトルート

layoutを使用すると、レイアウトルートはその子に対して新しいネストを作成しますが、URLにセグメントを追加しません。ルートルートに似ていますが、任意のレベルに追加できます。

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

export default [
  layout("./marketing/layout.tsx", [
    index("./marketing/home.tsx"),
    route("contact", "./marketing/contact.tsx"),
  ]),
  ...prefix("projects", [
    index("./projects/home.tsx"),
    layout("./projects/project-layout.tsx", [
      route(":pid", "./projects/project.tsx"),
      route(":pid/edit", "./projects/edit-project.tsx"),
    ]),
  ]),
] satisfies RouteConfig;

インデックスルート

index(componentFile),

インデックスルートは、親のURLで親のOutletにレンダリングされます(デフォルトの子ルートのように)。

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

export default [
  // renders into the root.tsx Outlet at /
  index("./home.tsx"),
  route("dashboard", "./dashboard.tsx", [
    // renders into the dashboard.tsx Outlet at /dashboard
    index("./dashboard-home.tsx"),
    route("settings", "./dashboard-settings.tsx"),
  ]),
] satisfies RouteConfig;

インデックスルートには子が存在できないことに注意してください。

ルートプレフィックス

prefixを使用すると、親ルートファイルを作成せずに、ルートのセットにパスプレフィックスを追加できます。

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

export default [
  layout("./marketing/layout.tsx", [
    index("./marketing/home.tsx"),
    route("contact", "./marketing/contact.tsx"),
  ]),
  ...prefix("projects", [
    index("./projects/home.tsx"),
    layout("./projects/project-layout.tsx", [
      route(":pid", "./projects/project.tsx"),
      route(":pid/edit", "./projects/edit-project.tsx"),
    ]),
  ]),
] satisfies RouteConfig;

動的セグメント

パスセグメントが:で始まる場合、それは「動的セグメント」になります。ルートがURLと一致すると、動的セグメントはURLから解析され、他のルーターAPIにparamsとして提供されます。

route("teams/:teamId", "./team.tsx"),
import type { Route } from "./+types/team";

export async function loader({ params }: Route.LoaderArgs) {
  //                           ^? { teamId: string }
}

export default function Component({
  params,
}: Route.ComponentProps) {
  params.teamId;
  //        ^ string
}

1つのルートパスに複数の動的セグメントを含めることができます。

route("c/:categoryId/p/:productId", "./product.tsx"),
import type { Route } from "./+types/product";

async function loader({ params }: LoaderArgs) {
  //                    ^? { categoryId: string; productId: string }
}

オプションセグメント

セグメントの末尾に?を追加することで、ルートセグメントをオプションにすることができます。

route(":lang?/categories", "./categories.tsx"),

オプションの静的セグメントも使用できます。

route("users/:userId/edit?", "./user.tsx");

スプラット

「キャッチオール」セグメントまたは「スター」セグメントとも呼ばれます。ルートパスパターンが/*で終わる場合、他の/文字を含む、/に続く任意の文字と一致します。

route("files/*", "./files.tsx"),
export async function loader({ params }: Route.LoaderArgs) {
  // params["*"] will contain the remaining URL after files/
}

*を分割代入できます。新しい名前を割り当てるだけです。一般的な名前はsplatです。

const { "*": splat } = params;

コンポーネントルート

URLと一致するコンポーネントをコンポーネントツリーの任意の場所で使用することもできます。

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>
  );
}

これらのルートは、データの読み込み、アクション、コード分割、またはその他のルートモジュール機能には関与しないため、ユースケースはルートモジュールよりも制限されます。


次へ: ルートモジュール

ドキュメントと例 CC 4.0