
React Router v7 の歩き方 - Declarative / Data / Framework の3モードと Remix 統合後の姿
「React Router って、ただの URL とコンポーネントの対応づけでしょ?」——そう思っている人ほど、React Router v7 を見ると驚くはずです。v7 は、単なるルーターからローダー・アクションを持つデータ層、さらにはSSR まで含むフルスタックのフレームワークまで、段階的に姿を変えられる作りになりました。
その鍵が 3つのモード(Declarative / Data / Framework)です。この記事では、各モードが何を足すのか、Remix が React Router v7 に統合された経緯、そして Next.js 以外の選択肢としてどう位置づけるかを整理します。
3つのモード: 必要なだけ機能を足す
React Router v7 は、同じライブラリでありながら3段階の使い方を選べます。下にいくほど機能が増えます。
| モード | 何ができるか | 主な API |
|---|---|---|
| Declarative | URL とコンポーネントの対応、ナビゲーション | <BrowserRouter>、<Link>、useNavigate、useLocation |
| Data | +データ読み込み・更新・保留状態 | createBrowserRouter、loader、action、useFetcher |
| Framework | +Vite プラグインで SSR・型安全・コード分割 | @react-router/dev、ファイルベースルート、型付き Route Module |
1. Declarative モード(一番素朴)
従来イメージどおりの「ルーター」です。URL に応じてコンポーネントを出し、リンクで遷移する。
import { BrowserRouter } from 'react-router';
ReactDOM.createRoot(root).render(
<BrowserRouter>
<App />
</BrowserRouter>,
);<Link>・useNavigate・useLocation といった、おなじみの API でアクティブ状態やナビゲーションを扱います。
2. Data モード(データ駆動)
ここからが v7 の本領です。ルート設定を React のレンダリングの外に出すことで、データの読み込み(loader)・更新(action)・保留状態などを扱えるようになります。
import { createBrowserRouter, RouterProvider } from 'react-router';
const router = createBrowserRouter([
{
path: '/',
Component: Root,
loader: loadRootData,
},
]);
ReactDOM.createRoot(root).render(<RouterProvider router={router} />);「コンポーネントの中で useEffect でデータを取る」のではなく、ルートに紐づいた loader がレンダリング前にデータを用意する——この発想の転換が肝です(useEffect の事故を減らす話は React useEffect 完全ガイドも参照)。
3. Framework モード(フルスタック)
最上位が Framework モードです。Data モードを @react-router/dev の Vite プラグインでラップし、フルスタックの体験を足します。
-
型安全な
hrefと Route Module API - 賢いコード分割
- SPA / SSR / 静的レンダリングの各戦略
ルートはファイルベースで定義し、パラメータまで型が付きます。
import { index, route } from '@react-router/dev/routes';
export default [
index('./home.tsx'),
route('products/:pid', './product.tsx'),
];import { Route } from './+types/product.tsx';
export async function loader({ params }: Route.LoaderArgs) {
const product = await getProduct(params.pid);
return { product };
}
export default function Product({ loaderData }: Route.ComponentProps) {
return <div>{loaderData.product.name}</div>;
}Route.LoaderArgs や Route.ComponentProps で、params や loaderData に自動で型が付くのがポイントです。新規プロジェクトは create-react-router で雛形を作れます。Vite ベースなので、ビルド周りも素直です。
Remix はどこへ行ったのか
「Remix を使っていたけど、これからどうなるの?」という人も多いはずです。答えはシンプルで、React Router v7 は Remix v2 の「次のバージョン」です。Remix は React Router v7 に統合され、そのFramework モードが実質的に Remix の進化形になりました。
Remix v1 → Remix v2 → React Router v7(Framework モード)つまり「Remix の loader / action / ネストルート」という資産は、React Router v7 の Framework モードにそのまま引き継がれています。Remix の歴史と v3で書いた流れの、現在の到達点がここです。
Next.js 以外の選択肢としての立ち位置
NOTE
React Router v7 の良さは、「必要なだけの段階を選べる」ことです。既存の React SPA は Declarative のまま動かし、データ層が欲しくなったら Data モードへ、SSR が要るなら Framework モードへ——と段階的に寄せられる。「最初からフルスタック前提」の Next.js App Router とは、ここの思想が違います。
ざっくりした使い分けの目安です。
| 状況 | 向いている選択 |
|---|---|
| 既存の React SPA を活かしたい | React Router(Declarative → 段階的に拡張) |
| データ駆動だが SSR は不要 | React Router(Data モード) |
| SSR・フルスタックを React Router 流で | React Router(Framework モード/旧 Remix) |
| 最初からフルスタック・RSC 前提 | Next.js App Router |
「Next.js ほど重くしたくない」「既存 SPA を壊さず段階的にサーバー寄りへ寄せたい」案件で、React Router v7 は現実的な選択肢になります。
まとめ
- React Router v7 は Declarative / Data / Framework の3モード。下にいくほど機能が増え、必要なだけ選べる
- Declarative=従来のルーター、Data=
loader/actionのデータ駆動、Framework=Vite プラグインで SSR・型安全・コード分割まで - React Router v7 は Remix v2 の次版。Remix は統合され、Framework モードがその進化形
- Framework モードはファイルベースルート+型付き Route Module(
Route.LoaderArgs等)。雛形はcreate-react-router - 「段階的に拡張できる」のが Next.js との思想差。既存 SPA を活かしつつサーバー寄りへ寄せたい現場に向く
「ただのルーター」という認識を一度アップデートすると、React Router v7 は「必要なところまで育てられるフレームワーク」として見えてきます。既存の React 資産があるほど、その段階性がありがたいはずです。