hydrate
hydrate
を使用すると、React 17 以前で react-dom/server
によって以前に生成されたブラウザの DOM ノードの HTML コンテンツ内に 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 におけるReactDOM Server
のメソッド(例:renderToString(<App />)
)でレンダーされた JSX の一部である<App />
のようなものです。 -
domNode
: サーバー上でルート要素としてレンダーされた DOM 要素。 -
省略可能:
callback
: 関数。渡された場合、React はコンポーネントのハイドレーション後にそれを呼び出します。
返り値
hydrate
は null を返します。
注意点
hydrate
は、レンダーされたコンテンツが、サーバーでレンダーされたコンテンツと同一であることを期待しています。React はテキストコンテンツの差異を修正できますが、不一致はバグとして扱い修正する必要があります。- 開発モードでは、React はハイドレーション中の不一致について警告します。不一致が発生した場合、属性の違いが修正される保証はありません。これはパフォーマンス上の理由から重要です。なぜならほとんどのアプリでは、不一致はまれであり、すべてのマークアップを検証することは非常に高コストになるからです。
- アプリには通常、1 つだけ
hydrate
呼び出しが存在するでしょう。フレームワークを使用している場合、フレームワークがこの呼び出しを行うかもしれません。 - HTML が既にレンダーされていないクライアントレンダリングの場合、
hydrate()
はサポートされていません。代わりに、React 17 以前では render()、React 18 以降では createRoot() を使用してください。
使用法
hydrate
を呼び出して、React コンポーネントをサーバーレンダリングされた ブラウザの DOM ノードにアタッチします。
import { hydrate } from 'react-dom';
hydrate(<App />, document.getElementById('root'));
hydrate()
を使用して、クライアントのみのアプリ(サーバーレンダリングされた HTML がないアプリ)をレンダーすることはサポートされていません。代わりに、React 17 以前では render()
、React 18 以降では createRoot()
を使用してください。
サーバーレンダリングされた HTML のハイドレーション
React では、「ハイドレーション」とは、サーバー環境の React によって既にレンダリングされた既存の HTML に React が「アタッチ」する方法を指します。ハイドレーション中、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 回のレンダーを行うことができます。クライアントで異なるものをレンダーするコンポーネントは、以下の isClient
のような state 変数を読み取ることができます。この変数は、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> ); }
この方法では、初回のレンダーはサーバと同じコンテンツをレンダーし、不一致を回避しますが、追加のパスがハイドレーションの直後に同期的に行われます。