hydrate
允許您在瀏覽器 DOM 節點中顯示 React 元件,該節點的 HTML 內容之前由 React 17 及以下版本的 react-dom/server
生成。
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 程式碼段,它在 React 17 中使用ReactDOM Server
方法(如renderToString(<App />)
)渲染。 -
domNode
:在伺服器上渲染為根元素的 DOM 元素。 -
可選:
callback
:一個函式。如果傳遞,React 將在您的元件完成 hydration 後呼叫它。
返回值
hydrate
會返回 null。
注意事項
hydrate
希望渲染的內容與服務端渲染的內容完全相同。React 可以修補文字內容的差異,但你應該將不匹配視為錯誤並修復它們。- 在開發模式下,React 會在 hydration 過程中針對不匹配發出警告。但不保證屬性差異會在不匹配的情況下得到修補。這對於效能來說很重要,因為在大多數應用程式中,不匹配的情況很少見,因此驗證所有標記的成本過高。
- 你的應用程式中很可能只有一個
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+ 中)。
hydrate 服務端渲染的 HTML
在 React 中,“hydration” 是指 React 如何“附加”到已由 React 在服務端環境中渲染的現有 HTML。在 hydration 過程中,React 將嘗試將事件監聽器附加到現有的標記,並在客戶端接管應用程式的渲染。
在完全使用 React 構建的應用程式中,通常只會在啟動時 hydrate 一個“根”元件,一次性完成整個應用程式的 hydrate。
import './styles.css'; import { hydrate } from 'react-dom'; import App from './App.js'; hydrate(<App />, document.getElementById('root'));
通常情況下,你不應該再次呼叫 hydrate
,也不應該在更多的地方呼叫它。從現在開始,React 將管理應用程式的 DOM。要更新 UI,你的元件將 使用狀態。
有關 hydration 的更多資訊,請參閱 hydrateRoot
的文件。
抑制不可避免的 hydration 不匹配錯誤
如果單個元素的屬性或文字內容在服務端和客戶端之間不可避免地不同(例如,時間戳),則可以抑制 hydration 不匹配警告。
要抑制元素上的 hydration 警告,請新增 suppressHydrationWarning={true}
export default function App() { return ( <h1 suppressHydrationWarning={true}> Current Date: {new Date().toLocaleDateString()} </h1> ); }
這隻在一級深度有效,並且是一個應急方案。不要過度使用它。除非是文字內容,否則 React 仍然不會嘗試修補它,因此它可能會在以後的更新中保持不一致。
處理不同的客戶端和服務端內容
如果你有意需要在服務端和客戶端渲染不同的內容,則可以進行兩次渲染。在客戶端渲染不同內容的元件可以讀取 狀態變數,例如 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> ); }
這樣,第一次渲染將渲染與服務端相同的內容,避免不匹配,但在 hydration 之後會立即同步進行第二次渲染。