FEATUREわかったつもりの、その先へ
知る・学ぶ

ハイドレーション入門

HTMLが見えることと、Reactの操作処理が動くことは別の段階です。ハイドレーションの役割、SSRとの違い、表示の不一致が起きる理由を、時間軸と照合図で整理します。

CONTENTSこの記事の目次5項目

正直に言うと、私はフロントエンドにあまり自信がありません。調べたりAIに聞いたりしながら、「とりあえず画面が動いた」で先へ進んでしまうことがあります。そんな中で出会ったのが、「ハイドレーション」という言葉でした。

見た目を整える話なのか、データを読み込む話なのか。自分の言葉で説明できそうになかったので、一度立ち止まって調べてみました。今回はReactとNext.jsを例に、画面が表示されてから操作に反応するまでを整理してみます。

先に届いたHTMLを、Reactが引き継ぐ

ハイドレーション(hydration)は、サーバー側で用意されたHTMLに、ブラウザー側のReactが結び付き、状態やイベント処理を扱えるようにする段階です。すでにある画面の構造を使い、Reactがその後の表示更新を引き継ぎます。

たとえば「あとで行こ」という保存ボタン。HTMLだけでもボタンの形と文字を表示できますが、そのボタンに用意したReactのonClick処理が働くには、ブラウザー側のJavaScriptの準備が必要です。見えることと、用意した処理が動くことを分けると、役割が見えてきます。

説明用の架空の保存ボタンを使った自作図。実アプリの画面や処理時間の測定結果ではありません。

ただし、「ハイドレーションが終わるまで、何も操作できない」という意味ではありません。リンクで移動する、通常のフォームを送信するといったHTML標準の仕組みは、Reactの処理とは別にブラウザーが持っています。

SSR・CSRとは、どこが違う?

SSR(Server-Side Rendering)は、サーバー側でHTMLを生成すること。CSR(Client-Side Rendering)は、ブラウザー側のJavaScriptで表示を組み立てることです。ハイドレーションは、サーバー側で用意されたHTMLをブラウザー側の処理へ引き継ぐ段階を指します。

つまり、SSRとハイドレーションは「どちらを使うか」という二者択一ではありません。サーバーでHTMLを用意し、ブラウザーでそれを表示したあとにハイドレーションする、という組み合わせができます。ビルド時に事前生成したHTMLでも、この引き継ぎは行われます。

Next.jsのuse clientも、名前だけで判断しない

Next.jsのApp Routerでは、use clientは、状態やイベント処理などを使うClient Componentの境界を示します。「最初から最後までブラウザーだけで描く」という宣言ではありません。初回表示では、Client Componentもサーバー側で用意するHTMLに含まれ得ます。

Server ComponentとClient Componentも、SSRとCSRも、ハイドレーションも、同じ軸の分類ではなかったわけです。用語を一つ覚えるたびに全部を当てはめようとせず、「HTMLをどこで用意する話か」「操作の処理をどう引き継ぐ話か」を確認すると、混同しにくくなります。

ハイドレーションの不一致は、なぜ起きる?

Reactは、サーバー側で用意した内容と、ブラウザー側で最初に描こうとする内容が一致することを前提にします。この最初の表示が食い違うのが、hydration mismatch(ハイドレーションの不一致)です。

ブラウザー内の保存設定を読む場合の模式図。共通の初期表示を使う一例であり、すべての不一致を同じ方法で直すものではありません。

たとえば、ブラウザーのlocalStorageに保存したテーマ設定。サーバーではその値を直接読めないのに、ブラウザーの初回描画だけが保存設定を使うと、二つの表示が食い違うことがあります。

  • 時刻や乱数を描画時に計算し、サーバーとブラウザーで違う値になる。
  • windowやlocalStorageの有無によって、初回表示の内容を変えてしまう。
  • HTMLの不正な入れ子が、ブラウザーによって修正される。
  • ブラウザー拡張や配信経路の処理によって、HTMLが書き換わる。

まず、二つの「最初」を比べる

調べるときは、エラーが指す部品で「サーバーは何を表示したか」「ブラウザーは最初に何を表示しようとしたか」を比べます。時刻、乱数、保存設定など、環境によって答えが変わる材料を探すのが入り口です。

対処は原因に合わせます。同じ初期値を渡せるならそろえる。ブラウザーにしかない値なら、最初は共通の表示にして、useEffectで値を読み込んだ後に更新する方法があります。ただし、後から表示が変わるため、ちらつきや待ち時間も含めて設計する必要があります。

警告を抑えるsuppressHydrationWarningは、原因を直す機能ではありません。まずは一致しない理由を確認する。何でもuseEffectへ移したり、SSRを無効にしたりする前に、この順番を大切にしたいと思いました。

実際のHTMLと操作を比べるなら

AppliParkの別記事では、Next.jsの小さなカウンターを使い、生成されたHTMLにある文字と、ブラウザーでボタンを押した後の変化を比べています。今回整理した言葉を、具体的な表示と操作に結び付けて確認したい方はこちらもどうぞ。

READ MOREHTMLとhydrationを、カウンターで確かめる生成HTMLとクリック後の表示を比べた検証記事です。

「動いたからOK」の、その先へ

今回の理解を自分の言葉にすると、ハイドレーションは「先に届いたHTMLを、ブラウザー側のReactが引き継ぐ段階」。そして、その引き継ぎでは、サーバーとブラウザーの最初の表示をそろえることが大切でした。

フロントエンドが得意になった、と胸を張れるところまではまだ遠いです。それでも、次にこの言葉やエラーに出会ったら、ただ修正案を貼り付ける前に、どこが食い違ったのかを考えられそうです。

わからないことを、わからないままにしない。一つずつ調べて、自分の言葉で説明してみる。その繰り返しで、「なんとなく動かせる」から「理由を理解して作れる」エンジニアへ進んでいこうと思います。

参考資料・確認日

React公式「hydrateRoot」、Next.js公式「Server and Client Components」「Text content does not match server-rendered HTML」を参照しました。確認日:2026年11月5日。図は概念を説明するために自作したもので、実画面のキャプチャではありません。