hydrate
允许你在浏览器 DOM 节点内显示 React 组件,其 HTML 内容之前由 react-dom/server
在 React 17 及以下版本中生成。
¥hydrate
lets you display React components inside a browser DOM node whose HTML content was previously generated by react-dom/server
in React 17 and below.
hydrate(reactNode, domNode, callback?)
参考
¥Reference
hydrate(reactNode, domNode, callback?)
在 React 17 及更低版本中调用 hydrate
将 React“附加”到已由 React 在服务器环境中渲染的现有 HTML。
¥Call hydrate
in React 17 and below to “attach” React to existing HTML that was already rendered by React in a server environment.
import { hydrate } from 'react-dom';
hydrate(reactNode, domNode);
React 将附加到 domNode
中存在的 HTML,并接管管理其中的 DOM。完全使用 React 构建的应用通常只会对其根组件进行一次 hydrate
调用。
¥React will attach to the HTML that exists inside the domNode
, and take over managing the DOM inside it. An app fully built with React will usually only have one hydrate
call with its root component.
参数
¥Parameters
-
reactNode
:“React 节点” 用于渲染现有的 HTML。这通常是一段像<App />
这样的 JSX,它是用ReactDOM Server
方法渲染的,比如 React 17 中的renderToString(<App />)
。¥
reactNode
: The “React node” used to render the existing HTML. This will usually be a piece of JSX like<App />
which was rendered with aReactDOM Server
method such asrenderToString(<App />)
in React 17. -
domNode
:在服务器上渲染为根元素的 DOM 元素。¥
domNode
: A DOM element that was rendered as the root element on the server. -
可选的:
callback
:一个功能。如果通过,React 将在组件水化后调用它。¥optional:
callback
: A function. If passed, React will call it after your component is hydrated.
返回
¥Returns
hydrate
返回空值。
¥hydrate
returns null.
注意事项
¥Caveats
-
hydrate
期望渲染的内容与服务器渲染的内容相同。React 可以修补文本内容的差异,但你应该将不匹配视为错误并修复它们。¥
hydrate
expects the rendered content to be identical with the server-rendered content. React can patch up differences in text content, but you should treat mismatches as bugs and fix them. -
在开发模式下,React 会在水合作用期间警告不匹配。不保证在不匹配的情况下会修补属性差异。出于性能原因,这很重要,因为在大多数应用中,不匹配的情况很少见,因此验证所有标记的成本非常高。
¥In development mode, React warns about mismatches during hydration. There are no guarantees that attribute differences will be patched up in case of mismatches. This is important for performance reasons because in most apps, mismatches are rare, and so validating all markup would be prohibitively expensive.
-
你的应用中可能只有一个
hydrate
调用。如果你使用框架,它可能会为你执行此调用。¥You’ll likely have only one
hydrate
call in your app. If you use a framework, it might do this call for you. -
如果你的应用是客户端渲染的,但尚未渲染 HTML,则不支持使用
hydrate()
。请改用 render()(对于 React 17 及以下版本)或 createRoot()(对于 React 18+)。¥If your app is client-rendered with no HTML rendered already, using
hydrate()
is not supported. Use render() (for React 17 and below) or createRoot() (for React 18+) instead.
用法
¥Usage
调用 hydrate
将 React 组件 附加到服务器渲染的浏览器 DOM 节点。
¥Call hydrate
to attach a React component into a server-rendered browser DOM node.
import { hydrate } from 'react-dom';
hydrate(<App />, document.getElementById('root'));
不支持使用 hydrate()
渲染仅客户端应用(没有服务器渲染 HTML 的应用)。请改用 render()
(在 React 17 及以下版本中)或 createRoot()
(在 React 18+ 中)。
¥Using hydrate()
to render a client-only app (an app without server-rendered HTML) is not supported. Use render()
(in React 17 and below) or createRoot()
(in React 18+) instead.
Hydrating 服务器渲染的 HTML
¥Hydrating server-rendered HTML
在 React 中,“hydration” 是如何将 React “attaches” 用于已在服务器环境中由 React 渲染的现有 HTML。在水合作用期间,React 将尝试将事件监听器附加到现有标记并接管在客户端上渲染应用。
¥In React, “hydration” is how React “attaches” to existing HTML that was already rendered by React in a server environment. During hydration, React will attempt to attach event listeners to the existing markup and take over rendering the app on the client.
在完全使用 React 构建的应用中,你通常只会在整个应用启动时水合一个 “根”。
¥In apps fully built with React, you will usually only hydrate one “root”, once at startup for your entire app.
import './styles.css'; import { hydrate } from 'react-dom'; import App from './App.js'; hydrate(<App />, document.getElementById('root'));
通常你不需要再次调用 hydrate
或在更多地方调用它。从这一点开始,React 将管理你应用的 DOM。要更新 UI,你的组件将 使用状态。
¥Usually you shouldn’t need to call hydrate
again or to call it in more places. From this point on, React will be managing the DOM of your application. To update the UI, your components will use state.
有关水合作用的更多信息,请参阅 hydrateRoot
。 的文档
¥For more information on hydration, see the docs for hydrateRoot
.
抑制不可避免的水合作用不匹配错误
¥Suppressing unavoidable hydration mismatch errors
如果单个元素的属性或文本内容在服务器和客户端之间不可避免地不同(例如,时间戳),你可以关闭水合作用不匹配警告。
¥If a single element’s attribute or text content is unavoidably different between the server and the client (for example, a timestamp), you may silence the hydration mismatch warning.
要消除元素上的水合作用警告,请添加 suppressHydrationWarning={true}
:
¥To silence hydration warnings on an element, add suppressHydrationWarning={true}
:
export default function App() { return ( <h1 suppressHydrationWarning={true}> Current Date: {new Date().toLocaleDateString()} </h1> ); }
这仅适用于一层深度,旨在成为应急方案。不要过度使用它。除非它是文本内容,否则 React 仍然不会尝试对其进行修补,因此在未来更新之前它可能会保持不一致。
¥This only works one level deep, and is intended to be an escape hatch. Don’t overuse it. Unless it’s text content, React still won’t attempt to patch it up, so it may remain inconsistent until future updates.
处理不同的客户端和服务器内容
¥Handling different client and server content
如果你有意需要在服务器和客户端上渲染不同的东西,你可以进行两次渲染。在客户端渲染不同内容的组件可以读取像 isClient
这样的 状态变量,你可以在 副作用 中将其设置为 true
:
¥If you intentionally need to render something different on the server and the client, you can do a two-pass rendering. Components that render something different on the client can read a state variable like isClient
, which you can set to true
in an Effect:
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> ); }
这样,初始渲染通道将渲染与服务器相同的内容,避免不匹配,但附加通道将在水合后立即同步发生。
¥This way the initial render pass will render the same content as the server, avoiding mismatches, but an additional pass will happen synchronously right after hydration.