はじめに
この記事で分かること
- React Router v7における「Dataモード」の基礎概念
- 最小構成でのLoaderの実装方法
- 簡単に動確できたのでこの記事では
Viteベースにしてます
- 簡単に動確できたのでこの記事では
- Route Objectによるネスト(入れ子)構造の作り方
想定読者
- React Router v6以降の新機能(Data APIs)を触ってみたい方
- useEffectでのデータ取得以外の方法でのデータ管理に触れてみたい方
なぜこの記事を書いたか
公式ドキュメントのチュートリアルをよりシンプルに分解し、Step by Stepで理解しながら実装できるようにガイドするため作成しました(多分シリーズ化します)。
Dataモードによる宣言的なデータフェッチ
React Router v7のDataモードは、従来の「useEffectによるデータ取得」ではなくloaderと呼ばれる機能でデータを取得します。
これにより、コンポーネント内の useEffect や loading 状態の管理をRouterの標準機能に任せられます。
前提知識の提示
- Reactの基礎(Props, Hooks)
-
fetchAPIによる非同期通信の理解 - 標準的な
react-router-domの利用経験
実装例:ネストされたルートとLoaderの活用
共通のナビゲーション(RootLayout)を持ちつつ、URLに応じて「一覧画面」や「詳細画面」を切り替える構成を作ります。
Loaderの作成
URLパラメータ(:userId)を受け取り、必要なデータを事前に取得する関数を定義します。
src/loaders/userDetailsLoader.ts
import { LoaderFunctionArgs } from "react-router";
export async function userDetailsLoader({ params }: LoaderFunctionArgs) {
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${params.userId}`);
if (!response.ok) throw new Error("ユーザーが見つかりません");
return response.json();
}
Componentの作成
useLoaderData フックを使い、Routerから渡されたデータを表示します。
src/pages/UserDetails.tsx
import { useLoaderData } from "react-router";
export default function UserDetails() {
const user = useLoaderData() as any;
return (
<div>
<h2>ユーザー詳細</h2>
<p><strong>名前:</strong> {user.name}</p>
<p><strong>メール:</strong> {user.email}</p>
</div>
);
}
Route Objectの定義(main.tsx)
createBrowserRouter 内で children を使い、親子関係を定義します。
src/main.tsx
import { createBrowserRouter, RouterProvider } from "react-router";
import RootLayout from "./layouts/RootLayout";
import App from "./App";
import UserList from "./pages/UserList";
import UserDetails from "./pages/UserDetails";
import { userLoader } from "./loaders/userLoader";
import { userDetailsLoader } from "./loaders/userDetailsLoader";
const router = createBrowserRouter([
{
path: "/",
Component: RootLayout, // 親(共通レイアウト)
children: [
{
index: true,
Component: App,
},
{
path: "users",
Component: UserList,
loader: userLoader,
},
{
path: "users/:userId",
Component: UserDetails,
loader: userDetailsLoader,
},
],
},
]);
- 注意点など
-
Outletの配置: 親コンポーネント(RootLayout)内に
<Outlet />を配置しないと、子ルートが表示されない -
Loader内でのエラー: 通信エラーなどは自動的に検知されます。適切なエラー画面を表示するには
errorElementの設定が推奨-
ErrorBoundaryの話は次回以降に持ち越し
-
-
Outletの配置: 親コンポーネント(RootLayout)内に
まとめ
- Dataモードは、ページ遷移と並行してデータを取得する高速な手法
- Loaderを定義することで、コンポーネントから「データ取得の責任」を分離し、レンダリングを最適化可能
- Route ObjectとOutletを活用すれば、共通UI(ヘッダー等)の再レンダリングを抑えつつ、動的な画面遷移が可能
続く(かも)。