React Router v7は、Reactアプリケーションのルーティングを強化するための最新バージョンであり、Remixとの統合によりフルスタックフレームワークとしての機能も備えています。本記事では、React Router v7の主な特徴と基本的な使い方について解説します。
[目次を開く]
React Router v7の主な特徴
- 複数のルーティング戦略: React Router v7では、以下の3つのルーティング方法が提供されています。
- Configベースのルーティング:
routes.ts
ファイルにJSONライクな形式でルートを定義します。 - コンポーネントベースのルーティング: Reactコンポーネントを直接ルートに関連付けます。
- ファイルベースのルーティング: ファイル名やフォルダ構造に基づいて自動的にルーティングを生成します。
※各ルーティングのメリットとデメリット
コンフィグベースのルーティング(Config-based Routing)
概要
routes.ts
などの設定ファイルに、ルート情報をオブジェクト形式で定義する方法です。メリット
- 明確な構造: ルート設定が一箇所に集約され、アプリケーションの全体構造を把握しやすい。
- 柔軟性: 動的ルートやネストされたルートの設定が容易で、複雑なルーティングにも対応可能。
- 型安全性: TypeScriptとの組み合わせで、ルートパラメータやローダーデータの型安全性を確保できる。
デメリット
- 初期設定の手間: 設定ファイルの作成や管理に時間がかかる場合がある。
- 冗長性: 小規模なアプリケーションでは、設定が過剰になることも。
適用例
大規模なアプリケーションや複雑なルーティング構成が必要な場合に適しています。
コンポーネントベースのルーティング(Component-based Routing)
概要
Reactコンポーネント内で直接ルートを定義する方法です。
メリット
- 直感的な定義: コンポーネント内でルートを定義でき、視覚的に理解しやすい。
- 迅速な開発: 小規模なアプリケーションやシンプルなルーティングに適しており、迅速に実装可能。
デメリット
- スケーラビリティの制限: アプリケーションが大規模化すると、管理が難しくなる可能性がある。
- コードの分散: ルート定義が複数のコンポーネントに分散すると、全体の把握が困難になることも。
適用例
小規模なプロジェクトや単純なルーティング構成に適しています。
ファイルベースのルーティング(File-based Routing)
概要
ファイルやディレクトリの構造に基づいて自動的にルートを生成する方法です。
メリット
- 自動化: ファイル構造に従ってルートが生成されるため、手動での設定が不要。
- 開発効率の向上: 新しいページの追加がファイル作成だけで完了し、迅速な開発が可能。
デメリット
- 柔軟性の制限: 特殊なルーティング要件や複雑な構成には対応しにくい場合がある。
- 学習コスト: 独自のファイル命名規則やディレクトリ構成を理解する必要がある。
適用例
中規模から大規模なプロジェクトで、ページ数が多く頻繁に変更が発生する場合に適しています。
各ルーティングのメリットとデメリット
- Configベースのルーティング:
- データローディングとアクション:
loader
やaction
を使用して、ルートごとにデータの取得や更新が可能です。これにより、サーバーサイドレンダリング(SSR)や静的プリレンダリングが容易になります。 - 型安全性の向上: 新しい
typegen
により、ルートパラメータやローダーデータ、アクションなどに対して型安全性が提供され、開発者はエラーを未然に防ぐことができます。
React Router v7の基本的な使い方
インストール
React Router v7は以下のコマンドでインストールできます。
npx create-react-router@latest react-router-v7-sdudy
コマンドを実行すると対話型プロンプトが開始されます。

※基本的にはYesで進んで頂いて大丈夫です。
Git使いますか?npmを使ってインストールしますか?という感じのことを聞かれます。
インストールが完了したらnpm run dev
で開発用サーバーを起動し、localhostにアクセスしてみましょう。以下のような画面が表示されていればOKです。

ルートの定義
今回は、Configベースのルーティングを使用して、routes.ts
ファイルにルートを定義します。
import { 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(":city/:id", "./concerts/show.tsx"),
route("trending", "./concerts/trending.tsx"),
]),
];
この設定により、各ルートが自動的にコード分割され、パラメータとデータの型安全性が提供されます。
データローディング
各ルートでloader
を使用してデータを取得できます。
export async function loader({ params }: Route.LoaderArgs) {
const [show, isLiked] = await Promise.all([
fakeDb.find("show", params.id),
fakeIsLiked(params.city),
]);
return { show, isLiked };
}
これにより、コンポーネントがレンダリングされる前に必要なデータを取得し、ユーザーに表示できます。
コンポーネントでのデータ使用
useLoaderData
フックを使用して、loader
から取得したデータにアクセスできます。
import { useLoaderData } from "react-router";
export default function Show() {
const { show, isLiked } = useLoaderData();
return (
<div>
<h1>{show.name}</h1>
<p>{show.description}</p>
<form method="post">
<button type="submit" name="liked" value={isLiked ? 0 : 1}>
{isLiked ? "Remove" : "Save"}
</button>
</form>
</div>
);
}
これにより、取得したデータをコンポーネント内で簡単に利用できます。
アクションの定義
action
を使用して、フォームの送信やデータの更新を処理できます。
export async function action({ request, params }: Route.LoaderArgs) {
const formData = await request.formData();
await fakeSetLikedShow(formData.get("liked"));
return { ok: true };
}
これにより、ユーザーの操作に応じてデータを更新し、ページ上のすべてのデータの再検証をトリガーして、UIを自動的に最新の状態に保つことができます。
まとめ
React Router v7は、従来のルーティング機能に加えて、データローディングや型安全性の向上など、多くの新機能を提供しています。これにより、Reactアプリケーションの開発がより効率的かつ強力になります。