先记住这个答案
如果容器里已经有同一 React 树生成的服务端 HTML,应使用 hydrateRoot 并传入对应组件,让 React 尝试复用已有节点。如果是需要由客户端新建界面的容器,使用 createRoot 后调用 root.render。两者都从 react-dom/client 导入,并返回可更新和卸载的根对象。旧 react-dom 中的 render 与 hydrate 在 React 18 被弃用、在 React 19 被移除;框架通常负责这些入口,业务组件不应重复接管同一容器。
- 已有对应 SSR HTML 使用 hydrateRoot
- 新建客户端界面使用 createRoot 再 render
- React 19 已移除旧 render 与 hydrate
两种启动方式对应不同初始条件
createRoot 为容器建立客户端根,首次 render 会生成这棵组件树的界面。如果容器中原本塞着 SSR 内容,再按这种方式首次渲染,就不能把原节点复用当作保证;需要复用时应走 hydration 路径。
hydrateRoot 在启动时就接收 React 节点,要求它的首次输出与现有服务端 HTML 一致。它不是检测任意 DOM 后自动猜出组件状态,也不支持把一个空的纯 CSR 容器当作已有 SSR 界面来接管。
import type { ReactNode } from 'react';
import { createRoot, hydrateRoot } from 'react-dom/client';
export function startApplication(
container: HTMLElement,
tree: ReactNode,
mode: 'server-html' | 'client-only'
) {
if (mode === 'server-html') {
return hydrateRoot(container, tree);
}
const root = createRoot(container);
root.render(tree);
return root;
}mode 由实际的服务端或客户端入口约定提供,不是通过容器有没有子节点随意猜测。宿主应只启动一次,并在真正移除该应用时调用返回根的 unmount;框架已管理入口时不需要再调用此函数。
后续更新沿用根,不要重复启动
启动后应通过组件状态或已有 root.render 更新界面,而不是每次数据变化都调用 createRoot 或 hydrateRoot。重复创建根会打乱容器所有权,也无法替代正常的组件更新和卸载管理。
对于 hydration 尚未完成的根,过早调用 root.render 可能使 React 清除服务端内容并切换整个根到客户端渲染。应优先沿用框架的数据和更新流程,避免在启动阶段另行插入抢先更新。
版本迁移要同时核对导入与行为
React 18 引入这组客户端根 API,旧入口在当时进入弃用状态;React 19 已移除旧 render 和 hydrate。只替换函数名而保留旧参数顺序、旧卸载方法或重复初始化逻辑,并不能完成正确迁移。
升级后应检查初始内容是否复用、事件是否可用、卸载是否清理,以及开发模式有没有根重复创建或 hydration 差异。若应用由 Next.js 等框架启动,应按框架升级约定处理,不能绕过框架手动接管页面根。
容易答错的地方
- 看见容器非空就使用 hydrateRoot
- 容器可能包含加载提示、手写标记或第三方节点,这些内容未必对应传入的 React 树。入口需要明确内容生成协议;随意 hydration 会制造不匹配,而不是获得免费复用。
- 为每次数据变化新建一个根
- 根是容器的长期管理对象,不是每次更新的临时渲染命令。重复创建会产生所有权冲突和清理困难,应保存既有根或让组件状态驱动更新,并在应用真正结束时统一卸载。
面试官还会怎么问?
hydrateRoot 返回后能立即假定所有交互就绪吗?
不能把函数返回等同于整个页面所有边界完成接管。代码、数据和调度仍可能影响具体子树,尤其有挂起边界时;应验证目标交互实际可用,避免用返回时刻作为全页面就绪指标。
可以在一个页面有多个根吗?
可以在互不重叠的独立容器中使用多个根,例如逐步接入既有页面。每个根都需要清楚的生命周期与数据边界;使用 useId 时还应核对服务端和客户端一致的 identifierPrefix,避免标识冲突。
hydrateRoot 会自动修补所有旧 HTML 吗?
不会。它要求两端首次输出一致,官方明确不保证属性差异都被修补。发现不匹配应修复数据、结构或环境差异,不能把 hydration 当成任意 HTML 到 React 界面的自动纠错器。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。