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