ハイドレーション入門
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日。図は概念を説明するために自作したもので、実画面のキャプチャではありません。