目次
22 章

なぜ Next.js と Server Components なのか

クライアントサイド React の限界と Server Components が解決する問題、CSR・SSR・RSC の違いを整理します。本書全体の転換点となる章です。

第21章までで第3部(TypeScript と一緒に)が締めくくられました。第1部ではコンポーネント・props・state・イベント・フォームを、第2部ではエフェクト・Context・フック・パフォーマンス・ルーティングを、第3部ではすべてのコードに型の安全網をかけました。本章から第4部が始まります。本書の転換点となる部です。

これまで見てきたすべての React コードは クライアントサイド でした。第21章の最後の節でプレビューした RSC モデル、つまりサーバーで直接フェッチし、クライアントの useEffect + fetch がほぼ消えるモデルの背景を本章で一度整理します。コードはほとんどありません。なぜ 新しいモデルが必要なのか、それが何を解決するのかをまず明確にしておくことが、続く第23~27章の理解に決定的だからです。

CSR — これまでやってきた方法 #

本書の第1~3部で作ったすべての React アプリは CSR(Client-Side Rendering) 方式でした。

CSR の流れ
1. ブラウザが空の HTML を受け取る(<div id="root"></div> だけの殻)
2. JavaScript バンドルをダウンロード
3. JavaScript を実行 → React が画面を描画
4. 必要なら fetch でデータを取得 → 再描画

この方式の利点は明確です。

  • 一度ロードされた後のページ遷移が速い(第15章で扱った SPA の利点)
  • サーバーは静的ファイルをホストすればよい(デプロイが単純)
  • インタラクションが豊富な UI の実装に強い

一方、欠点も明確です。

欠点 1. 最初の画面が遅い #

ブラウザが空の画面を受け取り、JavaScript をダウンロードし、実行し、ようやく画面が描画されます。インターネットが遅かったりデバイスが弱かったりすると、白い画面が長く見えてしまいます。第31章(パフォーマンス・バンドル・Web Vitals)で本格的に扱う LCP(Largest Contentful Paint)指標が直撃される箇所です。

欠点 2. SEO が難しい #

検索エンジンのクローラーは JavaScript を実行しないか、実行が遅れます。空の HTML だけを見ると本文をインデックスできず、検索露出が弱くなります。

欠点 3. JavaScript バンドルが大きくなる #

画面を描画するためのすべてのコード(コンポーネント、ライブラリ、データ処理ロジック)がクライアントにダウンロードされなければなりません。ライブラリを 1 つ追加するたびに、ユーザーが受け取る容量も増えていきます。

欠点 4. データフェッチがウォーターフォール #

サーバー応答 → JS ダウンロード → JS 実行 → fetch → またさらに fetch。段階ごとの待ち時間が累積します。第21章(fetch と API レスポンスの型付け)で作った useFetch パターンは、実はこのウォーターフォールの一断面を示しています。

SSR — サーバーで HTML を先に作る #

これらの問題を解決するために古典的に使われてきた方法が SSR(Server-Side Rendering) です。PHP や Ruby on Rails のような伝統的な Web サーバーモデルに戻る方式です。

SSR の流れ
1. ブラウザがページをリクエスト
2. サーバーで React を実行して HTML を作る
3. 完成した HTML を送信(コンテンツが既に入っている)
4. ブラウザがその HTML を表示
5. 同時に JS バンドルも受け取ってインタラクションを有効化(hydration)

hydration という単語が登場しました。これは「すでに描画された静的な HTML に JS でイベントハンドラを付けて、生きたコンポーネントにする」という意味です。乾いた HTML に JS の水を注いで蘇らせるという比喩から来ています。

SSR は最初の画面の速度と SEO の問題を解決します。ただし 依然としてすべてのコンポーネントコードがクライアントに送られて hydration される必要がある ため、バンドルサイズの問題はそのまま残ります。

RSC — React Server Components の登場 #

ここで React チームがもう一歩進みます。「そもそもクライアントに行く必要のないコンポーネントもあるのではないか?」

ブログ記事の本文を考えてみてください。一度描画された後、ユーザーがクリックしたり入力したりすることはあまりありません。ただデータを取ってきて画面に表示するだけです。こんなコンポーネントなら サーバーでのみ実行し、HTML(あるいはそれに近い表現)だけをクライアントに送れば よいのです。コンポーネントの JavaScript コード自体をクライアントに送る理由がありません。

これが React Server Components(RSC) の核心的なアイデアです。

RSC の流れ
1. ブラウザがページをリクエスト
2. サーバーで Server Components を実行
3. Server Components はデータベース・API を直接呼び出し可能
4. 結果をシリアライズした形で送信(HTML + Client Component の位置だけマーク)
5. クライアントは受け取った HTML を表示 + Client Components のみ hydrate

RSC が解決するもの。

  • バンドルサイズ削減 — 静的なコンポーネントのコードはそもそもクライアントに行かない
  • データフェッチが単純になる — Server Component で await db.query(...) するだけ(ネットワーク往復なし)
  • 機微情報の保護 — API キーや DB 認証情報がクライアントに絶対に露出しない
  • SEO と最初の画面の速度 — SSR の利点はそのまま

本書の第21章の最後の節で見た「RSC モデルのプレビュー」の背景は、まさにこの流れです。

では何がどこで実行されるのか #

この第4部で繰り返し登場する核心概念です。頭の中で先にイメージしておいてください。

コンポーネント種別実行場所使用可能使用不可
Server Componentsサーバーのみ(一度)DB 直接アクセス、環境変数、fs モジュール、async / awaituseState, useEffect, イベントハンドラ, ブラウザ API
Client Componentsサーバー(SSR)+ クライアント(hydration)useState, useEffect, イベント, ブラウザ APIDB 直接アクセス(セキュリティ)、fs

同じページの中で 2 種類が 共存 します。ページの静的なコンテンツ部分は Server Component、インタラクションが必要な部分(フォーム、トグル、ドロップダウンなど)は Client Component に分けます。この境界をうまく引くことがモダン React アプリ設計の核心です。続く第24章(Server vs Client Components)で本格的に扱います。

React 19 がこのモデルに加えるもの #

React 19 の正式リリースで、RSC の上で動作する新しい道具たちが安定化しました。本第4部で順番に出会うことになります。

  • use() フック(第26章) — Promise・Context の両方を解決できるフック。RSC で作った Promise を Client で解くときの核心
  • Server Actions(第27章) — <form action={serverFn}> の中でサーバー関数を直接呼び出す。フォーム・mutation の新標準
  • useActionStateuseFormStatususeOptimistic(第27章 + 第28章) — Server Actions と組み合わせるフック群
  • Asset Loading(preload、preconnect) — RSC streaming と自然に組み合わせられる

これらすべての新機能を一か所にまとめた章が第28章(React 19 新機能まとめ)です。第4部の本文で新機能が登場するたびに、第28章への cross-link が付きます。

Next.js との関係 #

React Server Components は React 自体の機能ですが、これを実際に使うにはビルドツールとサーバーインフラが必要 です。RSC をシリアライズし、ルーティングを処理し、キャッシュを管理し、サーバーを立てる作業を誰かがやってくれなければならないためです。

Next.js は React チームと最も緊密に協業するメタフレームワークで、RSC を正式にサポートする最も成熟した選択肢です(RemixWakuTanStack Start のような他の選択肢もあります)。この第4部では Next.js 15 を使います。本書の第6部キャップストーン(フルスタック Todo アプリ)も Next.js 15 の上で作ります。

注記
SchoolofWeb(schoolofweb.net)サイトは現在 Hugo で作られていますが、その前は Next.js で作られていました。この第4部のモデルでサイトを一度作った経験があるため、本書は単なる公式ドキュメントのまとめではなく、運用経験が織り込まれた視点になっています。

転換の核心 #

第4部を始める前に、最も重要なマインドセットが 2 つあります。

1. 「このコードはどこで実行されるのか?」を常に意識する #

これまで我々は「コードはすべてブラウザで動く」という単一の環境で生きていました。モダン React では 同じファイルの中でもサーバーで動くコードとクライアントで動くコードが混在し得ます。この境界を意識しないと、すぐに混乱に陥ります。

毎回自問してください。「この関数はサーバーで実行されるのか、クライアントで実行されるのか?」 そうすれば、データフェッチがどう動作すべきか、環境変数にアクセス可能か、イベントハンドラを付けてよいかが明確になります。

2. デフォルトは Server Component、必要なものだけ Client Component #

新しいコンポーネントを作るとき、デフォルトは Server Component です(Next.js App Router にて)。Client Component が必要な明確な理由(状態、イベント、ブラウザ API)があるときだけ、'use client' ディレクティブを付けて変換します。このデフォルトがバンドルサイズを小さく保つ核心です。

付録 A との関係 — 旧 React から移ってくる方へ #

第4部のモデルは旧 React(クラスコンポーネント・Pages Router・Redux-only・useEffect + fetch)とは動作方式が異なります。旧コードベースから本モデルに移る手順は付録 A(旧 React マイグレーション)に別途まとめてあります。第4部を読みながら旧パターンが頭に浮かぶたびに、付録 A を脇に置いておくと自然です。

第4部で扱う内容 #

続く第23~28章で順を追って扱う内容です。

  • 第23章 Next.js プロジェクトの開始、App Router のファイル構成、layout システム
  • 第24章 'use client' ディレクティブとサーバー / クライアントコンポーネントの境界
  • 第25章 Server Component での await fetch(...) パターン、キャッシュ
  • 第26章 Suspense と loading.tsxuse() フックでローディング処理
  • 第27章 Server Actions でフォーム送信と mutation を扱う
  • 第28章 React 19 新機能まとめ — Actions / useFormStatus / useOptimistic / use() / React Compiler / ref as prop

そして第6部キャップストーン(第34章)で、この第4部のすべての道具をフルスタック Todo アプリ 1 つにまとめます。

練習問題 #

本章はコードがほぼない概念章なので、練習問題もメタな形です。

  1. 自分で作ったことのある(または知っている)Web アプリを 1 つ選び、そのアプリのページ・コンポーネントを「これは Server Component が適切」「これは Client Component が適切」の 2 グループに分けてみてください。分岐基準は「このコンポーネントにインタラクション(state、イベント、ブラウザ API)があるか?」にすればよいです。
  2. CSR・SSR・RSC の違いを次の 3 つの指標で比較する小さな表を書いてみてください。(a) 最初の画面が見えるまでの時間、(b) SEO 親和性、(c) クライアントバンドルサイズ。3 つのモデルのトレードオフが頭に残れば、第4部が軽く読めます。
  3. 本書の第21章の最後の節(RSC プレビュー)のコードと、第21章の useFetch コードをもう一度比較してみてください。両モデルで useState / useEffect / cancelled フラグ / ローディング分岐がどこに消えたか / どこに移ったかを直接確認すれば、第4部への入り方がずっと自然になります。

一行まとめ: CSR は素早いインタラクションを与えるが最初の画面が遅く SEO が弱くバンドルが大きい。SSR は最初の画面と SEO を解決するが、依然としてすべてのコードがクライアントに行く。RSC は静的コンテンツをサーバーでのみ実行し、コード自体がクライアントに行かない。第4部の 2 つのマインドセット — (1)「このコードはどこで実行されるのか?」を常に意識、(2) デフォルトは Server Component、必要なものだけ Client Component。

次の章 #

次の 第23章 Next.js の開始と App Router では、実際に Next.js 15 プロジェクトを作り、App Router のファイルベースルーティングと layout システムを直接触ってみます。第15章(React Router)の動作方式と比較しながら、同じ問題(URL → 画面)を異なる方式で解く姿を見ていきます。

X