hydrate
讓您在瀏覽器 DOM 節點中顯示 React 元件,其 HTML 內容之前是由 react-dom/server
在 React 17 及以下版本中產生。
hydrate(reactNode, domNode, callback?)
參考
hydrate(reactNode, domNode, callback?)
在 React 17 及以下版本中呼叫 hydrate
,以將 React「附加」到伺服器環境中已由 React 呈現的現有 HTML。
import { hydrate } from 'react-dom';
hydrate(reactNode, domNode);
React 會附加到存在於 domNode
內的 HTML,並接管其內部 DOM 的管理。使用 React 完全建置的應用程式通常只會呼叫一次 hydrate
,並使用其根元件。
參數
-
reactNode
:用於呈現現有 HTML 的「React 節點」。這通常會是類似<App />
的 JSX 片段,並使用ReactDOM Server
方法呈現,例如 React 17 中的renderToString(<App />)
。 -
domNode
:在伺服器上作為根元素呈現的 DOM 元素。 -
選用:
callback
: 一個函式。如果傳遞,React 會在元件水化後呼叫它。
傳回
hydrate
傳回 null。
注意事項
hydrate
預期已呈現的內容與伺服器呈現的內容相同。React 可以修補文字內容的差異,但你應該將不匹配視為錯誤並加以修正。- 在開發模式中,React 會在水合期間對不匹配發出警告。無法保證在不匹配的情況下會修補屬性差異。這對於效能原因很重要,因為在大部分應用程式中,不匹配的情況很罕見,因此驗證所有標記會造成極大的負擔。
- 你的應用程式中可能只有一個
hydrate
呼叫。如果你使用架構,它可能會為你執行此呼叫。 - 如果你的應用程式是使用用戶端呈現,且尚未呈現 HTML,則不支援使用
hydrate()
。請使用 render()(適用於 React 17 及以下版本)或 createRoot()(適用於 React 18+)。
用法
呼叫 hydrate
以將 React 元件 附加到伺服器呈現的 瀏覽器 DOM 節點。
import { hydrate } from 'react-dom';
hydrate(<App />, document.getElementById('root'));
使用 hydrate()
渲染僅限用戶端的應用程式(沒有伺服器渲染 HTML 的應用程式)不受支援。請使用 render()
(在 React 17 及以下版本)或 createRoot()
(在 React 18+ 版本)。
水化伺服器渲染的 HTML
在 React 中,「水化」是 React 如何「附加」到已在伺服器環境中由 React 渲染的現有 HTML。在水化期間,React 將嘗試將事件監聽器附加到現有標記,並接管在用戶端渲染應用程式。
在完全使用 React 建置的應用程式中,您通常只會水化一個「根」,在應用程式的啟動時執行一次。
import './styles.css'; import { hydrate } from 'react-dom'; import App from './App.js'; hydrate(<App />, document.getElementById('root'));
通常你不需要再呼叫 hydrate
或在更多地方呼叫它。從這一點開始,React 將管理應用程式的 DOM。若要更新 UI,你的元件會 使用狀態。
有關水合的更多資訊,請參閱 hydrateRoot
的文件。
抑制不可避免的水合不匹配錯誤
如果單一元素的屬性或文字內容在伺服器和用戶端之間不可避免地不同(例如時間戳),你可以取消水合不匹配警告。
若要取消元素上的水合警告,請加入 suppressHydrationWarning={true}
export default function App() { return ( <h1 suppressHydrationWarning={true}> Current Date: {new Date().toLocaleDateString()} </h1> ); }
這只會作用一層,並且預計是一個逃生艙口。不要過度使用它。除非是文字內容,否則 React 仍然不會嘗試修補它,因此它可能會保持不一致,直到未來的更新。
處理不同的客戶端和伺服器內容
如果你有意需要在伺服器和客戶端呈現不同的內容,你可以進行兩次渲染。在客戶端呈現不同內容的元件可以讀取 狀態變數,例如 isClient
,你可以在 效果 中將其設定為 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> ); }
這樣,初始的渲染過程會呈現與伺服器相同的內容,避免不一致,但額外的過程會在水化後立即同步發生。