非推奨

この API は、React の将来のメジャーバージョンで削除される予定です。

React 18 では、hydratehydrateRoot に置き換えられました。React 18 で hydrate を使用すると、アプリが React 17 で実行されているかのように動作するという警告が表示されます。詳細については、こちらをご覧ください。

hydrate を使用すると、React 17 およびそれ以下のバージョンで react-dom/server によって事前に生成された HTML コンテンツを持つブラウザ DOM ノード内に React コンポーネントを表示できます。

hydrate(reactNode, domNode, callback?)

リファレンス

hydrate(reactNode, domNode, callback?)

React 17 およびそれ以下のバージョンで hydrate を呼び出して、サーバー環境で React によってすでにレンダリングされた既存の HTML に React を「アタッチ」します。

import { hydrate } from 'react-dom';

hydrate(reactNode, domNode);

React は domNode 内に存在する HTML にアタッチし、その中の DOM の管理を引き継ぎます。React で完全に構築されたアプリでは、通常、ルートコンポーネントに対して 1 つの hydrate 呼び出ししかありません。

詳細については、以下の例を参照してください。

パラメータ

  • reactNode: 既存の HTML をレンダリングするために使用される「React ノード」。これは通常、React 17 で renderToString(<App />) などの ReactDOM Server メソッドでレンダリングされた <App /> のような JSX の一部になります。

  • domNode: サーバー上のルート要素としてレンダリングされた DOM 要素

  • 任意: callback: 関数。渡された場合、React はコンポーネントがハイドレートされた後にそれを呼び出します。

戻り値

hydrate は null を返します。

注意点

  • hydrate は、レンダリングされたコンテンツがサーバーレンダリングされたコンテンツと同一であることを期待します。React はテキストコンテンツの差異を修正できますが、不一致はバグとして扱い、修正する必要があります。
  • 開発モードでは、React はハイドレーション中の不一致について警告します。不一致の場合に属性の差異が修正される保証はありません。ほとんどのアプリでは不一致はまれであるため、すべてのマークアップを検証することは非常にコストがかかるため、これはパフォーマンス上の理由から重要です。
  • 通常、アプリで hydrate の呼び出しは 1 回だけです。フレームワークを使用している場合は、この呼び出しを代わりに行ってくれることがあります。
  • アプリがすでに HTML がレンダリングされていないクライアントレンダリングの場合は、hydrate() の使用はサポートされていません。代わりに render()(React 17 以下の場合)または createRoot()(React 18 以上の場合)を使用してください。

使い方

hydrate を呼び出して、Reactコンポーネントをサーバーレンダリングされたブラウザの DOM ノードにアタッチします。

import { hydrate } from 'react-dom';

hydrate(<App />, document.getElementById('root'));

クライアント専用アプリ(サーバーレンダリングされた HTML がないアプリ)をレンダリングするために hydrate() を使用することはサポートされていません。代わりに render() (React 17 以下の場合) または createRoot() (React 18+ の場合) を使用します。

サーバーレンダリングされた HTML のハイドレーション

React において、「ハイドレーション」とは、React がサーバー環境で既にレンダリングされた既存の HTML に「アタッチ」する方法です。ハイドレーション中、React は既存のマークアップにイベントリスナーをアタッチし、クライアントでアプリのレンダリングを引き継ごうとします。

React で完全に構築されたアプリでは、通常、アプリ全体で起動時に 1 回だけ「ルート」をハイドレートします

import './styles.css';
import { hydrate } from 'react-dom';
import App from './App.js';

hydrate(<App />, document.getElementById('root'));

通常は、hydrate を再度呼び出したり、より多くの場所で呼び出す必要はありません。この時点から、React はアプリケーションの DOM を管理します。UI を更新するには、コンポーネントが stateを使用します。

ハイドレーションの詳細については、hydrateRoot のドキュメントを参照してください。


回避できないハイドレーションの不一致エラーの抑制

単一要素の属性またはテキストコンテンツが、サーバーとクライアントで避けられないほど異なる場合(たとえば、タイムスタンプ)、ハイドレーションの不一致警告を非表示にすることができます。

要素のハイドレーション警告を非表示にするには、suppressHydrationWarning={true} を追加します。

export default function App() {
  return (
    <h1 suppressHydrationWarning={true}>
      Current Date: {new Date().toLocaleDateString()}
    </h1>
  );
}

これは 1 レベルの深さでのみ機能し、エスケープハッチとして意図されています。使いすぎないでください。テキストコンテンツでない限り、React はそれを修正しようとしないため、将来の更新まで一貫性が保たれない可能性があります。


クライアントとサーバーの異なるコンテンツの処理

サーバーとクライアントで意図的に異なるものをレンダリングする必要がある場合は、2 パスレンダリングを行うことができます。クライアントで異なるものをレンダリングするコンポーネントは、state変数である isClient のようなものを読み取ることができ、Effect の中で true に設定できます。

import { useState, useEffect } from "react";

export default function App() {
  const [isClient, setIsClient] = useState(false);

  useEffect(() => {
    setIsClient(true);
  }, []);

  return (
    <h1>
      {isClient ? 'Is Client' : 'Is Server'}
    </h1>
  );
}

このようにすると、最初のレンダリングパスはサーバーと同じコンテンツをレンダリングし、不一致を回避しますが、ハイドレーションの直後に追加のパスが同期的に発生します。

落とし穴

このアプローチでは、コンポーネントを 2 回レンダリングする必要があるため、ハイドレーションが遅くなります。低速な接続でのユーザーエクスペリエンスに注意してください。JavaScript コードは、最初の HTML レンダリングよりも大幅に遅れてロードされる場合があるため、ハイドレーション直後に異なる UI をレンダリングすると、ユーザーにとって不快に感じる場合があります。