1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

React Router v7 →Next.js App Router 移行計画:API呼び出し編

Last updated at Posted at 2026-01-28

はじめに

今回は、React Router v7 SSR構成と
Next.js App Router のAPI呼び出しの違いと、
React Router v7 SSR構成からNext.js App Router へ移行する際のポイントをまとめてみました。

大きく異なる点として「API呼び出しの位置と責務」です。

表面的にはどちらも fetch を使っていますが、実際には次の点が根本的に異なります。

・いつ API を呼ぶのか
・どこで API を呼ぶのか
・誰の権限で API を呼ぶのか
・どのように再取得されるのか

この記事では、公式ドキュメントの説明を軸に、
React Router v7 の loader / action
Next.js App Router の Server Components / Server Actions

を どう対応付けて移行するかを解説します。

React Router v7(SSR)の API 呼び出しモデル

React Router v7(Framework モード)では、公式ドキュメントで次のように説明されています。

Data loading and mutations are handled by route loaders and actions.
UI components read data, but they don’t fetch it directly.

以下、日本語訳
データの読み込みと変更は、ルートローダーとアクションによって処理されます。
UIコンポーネントはデータを読み取りますが、直接取得することはありません。

基本構造(公式想定)

・API 呼び出しは loader / action に集約
・UI コンポーネントは データを消費するのみ
・ルーティングがデータ取得の単位

典型的なloader

export async function loader({ request }: LoaderFunctionArgs) {
  const session = await getSessionInfo(request)

  const res = await fetch(`${API_BASE}/customers`, {
    headers: {
      Authorization: `Bearer ${session.accessToken}`,
    },
  })

  return json(await res.json())
}

loader の特徴(公式仕様)

・request が必ず渡される
・Cookie / Header は request から取得
・ページ表示前に必ず実行
・action 実行後は loader が自動的に再実行

「ルート単位で API を呼ぶ」設計

action による更新系 API

export async function action({ request }: ActionFunctionArgs) {
  const formData = await request.formData()

  await fetch(`${API_BASE}/customers`, {
    method: 'POST',
    body: JSON.stringify(...),
  })

  return redirect('/customers')
}

action の特徴

・フォーム送信と密結合
・成功後は loader が再実行される前提
・再取得の責務は Router が持つ

Next.js App Router(RSCベース)の API 呼び出しモデル

公式ドキュメントの前提
Next.js App Router は React Server Components(RSC) を前提に設計されています。

Server Components allow you to fetch data on the server, closer to the data source.

以下日本語訳
サーバーコンポーネントを使用すると、データソースに近いサーバー上でデータを取得できます。

基本構造(公式想定)

・ページ自体が async
・コンポーネント内で直接 API を呼ぶ
・Server Component がデフォルト

export default async function Page() {
  const res = await fetch('https://internal-api/customers', {
    headers: {
      Authorization: `Bearer ${process.env.API_KEY}`,
    },
  })

  const customers = await res.json()
  return <CustomerList customers={customers} />
}

・loader という概念は存在しない
・React コンポーネント = データ取得の単位
(ページ内の取得に限定されない)
・fetch は Next.js 拡張版(キャッシュ前提)

「コンポーネント単位で API を呼ぶ」設計

Next.js の fetch が「ただの fetch ではない」理由

デフォルト挙動(公式仕様)

await fetch(url)

Next.js の fetch は内部的に
・自動キャッシュ
・同一リクエストのdedupe
・ページ遷移間で再利用

React Router の loader と違い、毎回実行されない

宣言的なキャッシュ制御(公式推奨)

常に最新が必要な場合

await fetch(url, { cache: 'no-store' })

時間ベース再生成(ISR)

await fetch(url, {
  next: { revalidate: 60 },
})

イベント駆動再取得(action 連動)

await fetch(url, {
  next: { tags: ['customers'] },
})
revalidateTag('customers')

結論:NextjsとReact Router v7の認証付き API 呼び出しの違い

React Router v7(ユーザー起点)

・request から Cookie / Token を取得
・API 呼び出しは ユーザー起点
・Authorization: Bearer

📘 公式(request ベース):

Next.js App Router(システム起点)

・Server Component で環境変数を直接利用可能
・API 呼び出しは システム起点(アプリ起点)
・コンポーネントが BFF になる

loader / action マッピング対応表(最終整理)

観点 React Router v7 SSR Next.js App Router
取得単位 ルート コンポーネント
取得場所 loader Server Component
更新 action Server Action / API
再取得 自動 明示(revalidate)
fetch 毎回実行 キャッシュ前提
認証 request中心 cookie / env中心
BFF 別途必要 コンポーネント内包

まとめ

React Router v7

ルーティングが API 呼び出しを管理する

Next.js App Router

React コンポーネントが API 呼び出しを管理する

移行時に意識すべきポイント

React Router v7 → Next.js App Router の移行は、
単なる技術スタックの変更では
ただ単に、React Router v7のloader を
Nextjsのpage.tsx に移すことではあらず

「ルーティング中心のデータ設計」から
「コンポーネント中心のデータ設計」への移行することです。

この視点を持つことで、
Next.js App Router が前提としている
Server Components / Server Actions の価値

正しく引き出せるようになります。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?