前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库React hydration mismatch 原因
ReReact服务端与流式渲染

React hydration mismatch 通常由哪些原因造成,怎么定位?

需要对齐的是服务端输出与客户端第一次渲染,而不是要求页面此后永远保持不变。

前端进阶之旅 · 一题精讲更新于 2026.09.06
React#服务端与流式渲染#Hydration#流处理
先看核心答案读代码示例
理解线索

从差异位置倒查三类输入

  1. 业务数据服务端和客户端是否使用同一初始快照
  2. 运行环境时间、随机数、语言、时区与浏览器 API 是否影响输出
  3. 标记结构HTML 是否合法,接管前是否被其他程序修改

客户端接管完成后通过 state 或 Effect 更新内容是正常更新;不要把后续合法变化误判成首次 hydration 差异。

核心回答

先记住这个答案

hydration mismatch 表示客户端首次渲染预期与浏览器中已有的服务端标记不一致。常见来源包括两端读取不同数据快照、渲染时生成时间或随机数、按 window 或设备状态分支、时区和本地化差异、无效 HTML 被浏览器修正,以及扩展或第三方脚本提前修改 DOM。定位时先保留原始响应、实际 DOM 和客户端初始输入,再缩小到首个不同节点;修复应恢复确定性输入或合法结构,而不是整片关闭警告。

  • 比较的是客户端第一次输出
  • 先核对数据再核对环境和结构
  • 浏览器解析后的 DOM 可能不同于原始字符串

先排查两端是否真的使用同一份数据

服务端取到商品库存十件,客户端启动时重新读取到九件,如果直接用新结果进行首次渲染,就可能与已有 HTML 冲突。应明确初始快照传递与后续重新验证时机,让首次接管使用对应的数据。

时间显示也有类似问题。服务端和浏览器各自取当前时间,即使格式相同也可能跨秒;指定相同时区只能解决部分格式差异,不能让两次不同的时间读取自动成为同一个输入。

把首次展示标签作为共享数据传递TSX
type PublishedTimeProps = {
  iso: string;
  initialLabel: string;
};

export default function PublishedTime({ iso, initialLabel }: PublishedTimeProps) {
  return <time dateTime={iso}>{initialLabel}</time>;
}

服务端生成一次 iso 与 initialLabel,并通过框架的数据机制把相同值交给客户端首次渲染。组件不在渲染中重新读取当前时间或猜测浏览器语言;需要本地化时,可以在接管后按明确策略更新。

再检查环境分支和浏览器解析结果

在渲染中根据 typeof window 是否存在返回两套结构,会让服务端与浏览器天然走不同分支。读取 matchMedia、localStorage 或默认语言也可能改变首次输出,应采用一致的初始值再更新,或划定合理客户端边界。

无效嵌套会被浏览器解析器修正,例如某些块元素放进段落后,实际 DOM 不再等于服务端字符串暗示的结构。检查时要同时看原始响应和元素树,单独比较 JSX 源码可能找不到解析阶段的改写。

最后隔离外部修改并缩小复现

浏览器扩展、翻译工具、第三方脚本或 CDN 转换都可能在接管前改动节点。可以用干净上下文与固定数据复现,再逐步启用相关因素;不能因为自己组件代码看起来一致,就认定警告一定是 React 误报。

调试应记录差异节点附近的组件路径、初始数据版本和发生环境,并注意去除用户敏感信息。先修首个结构或输入差异,再重试观察其他诊断,避免一次给整棵树加抑制属性而丢失根因。

回答前,多想一步

容易答错的地方

固定时区就认为所有时间差异都解决了
时区只影响时间解释和格式,两端分别读取当前时刻仍然可能不同。应共享时间值和初始标签,或明确接管后的更新时间;本地化库及运行环境差异也需要在实际部署环境中核对。
直接关闭 SSR 作为默认修复
关闭某个组件的服务端输出可能适合确实只依赖浏览器的功能,但也会改变首屏与可发现内容。应先确认差异来源,优先修复共享数据和结构,不能为隐藏错误无差别放弃整页服务端正文。
试着用自己的话回答

面试官还会怎么问?

为什么刷新时出错,站内跳转时不出错?

首次导航可能接管服务端 HTML,站内跳转则可能走客户端更新而没有同样的接管过程。应比较两条路径的数据来源与初始结构,不要把客户端跳转正常当成服务端输出已正确的证据。

CSS 差异也会触发 hydration 错误吗?

单纯样式计算结果不同不一定构成 React 标记差异,但服务端和客户端生成不同 class 或属性时可能出现诊断。应区分样式表加载问题与实际 DOM 属性不一致,再核对样式库的服务端集成。

可以先显示一致的初始提示,再读取浏览器状态吗?

可以,这属于两阶段展示策略,但需要接受额外更新与可能的视觉切换。应保证初始提示对用户有意义、布局稳定,并避免把公开页面关键正文全部推迟到客户端,尤其要验证弱网体验。

从一道题,走向一组知识

把知识连起来

服务端与流式渲染

React hydration 不匹配时如何恢复,会导致整个页面重建吗?

了解差异出现后 React 可能如何恢复和产生额外工作。

服务端与流式渲染

suppressHydrationWarning 适合什么情况,为什么不是通用修复?

区分可控例外与掩盖数据、结构错误的做法。

服务端与流式渲染

hydrateRoot 与 createRoot 如何选择,React 19 还支持旧 hydrate 吗?

确认根 API 与现有 HTML 的生成条件相匹配。

参考资料

  • React 官方:hydrateRoot 常见不匹配原因

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 先排查两端是否真的使用同一份数据
  3. 再检查环境分支和浏览器解析结果
  4. 最后隔离外部修改并缩小复现
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑