弃用

这个 API 将在 React 的未来主要版本中被删除。

¥This API will be removed in a future major version of React.

在 React 18 中,hydrate 已被 hydrateRoot 替换 在 React 18 中使用 hydrate 将警告你的应用将像运行 React 17 一样运行。在 在此处 了解更多。

¥In React 18, hydrate was replaced by hydrateRoot. Using hydrate in React 18 will warn that your app will behave as if it’s running React 17. Learn more here.

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.

请参阅下面的更多示例。

¥See more examples below.

参数

¥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 a ReactDOM Server method such as renderToString(<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

调用 hydrateReact 组件 附加到服务器渲染的浏览器 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.

易犯错误

这种方法会使水合作用变慢,因为你的组件必须渲染两次。注意慢速连接时的用户体验。JavaScript 代码的加载时间可能明显晚于初始 HTML 渲染,因此在水合后立即渲染不同的 UI 可能会让用户感到不协调。

¥This approach makes hydration slower because your components have to render twice. Be mindful of the user experience on slow connections. The JavaScript code may load significantly later than the initial HTML render, so rendering a different UI immediately after hydration may feel jarring to the user.


React 中文网 - 粤ICP备13048890号