React Hydration Mismatch
React 在 SSR 或 SSG 场景下 hydration mismatch 的含义、常见原因,以及它与首屏直出和客户端首次渲染一致性的关系。
#tech / dev / frame
#resource / react
#type / concept
#status / growing
[!info] related notes
React Hydration Mismatch
React 做 hydration 时,最关键的前提是客户端第一次渲染结果要能和服务端给出的 HTML 对上;一旦对不上,就容易出现 mismatch。
一句话定义
Hydration mismatch 是指 React 在客户端接管服务端 HTML 时,发现客户端首次渲染结果和现有 DOM 结构或内容不一致。
为什么会发生
- 服务端和客户端使用了不同的数据
- 首次渲染依赖了只在浏览器存在的环境信息
- 首次渲染包含随机数、时间戳、区域化格式等不稳定内容
- 条件渲染在服务端和客户端走了不同分支
它为什么麻烦
- 可能触发警告
- 可能让局部 DOM 被重新生成
- 会削弱 SSR 直出带来的稳定体验
- 严重时会让首屏和交互接管阶段出现闪动或异常
怎么理解它和 React 的关系
- SSR 给了用户一份先看到的 HTML
- React hydration 负责在客户端接管这份 HTML
- mismatch 本质上就是“服务端输出”和“客户端第一次 render”没有对齐
常见误区
- 以为只要用了 SSR,就天然不会有首屏不一致问题
- 以为 hydration warning 只是开发环境噪音
- 把所有浏览器专属逻辑都直接写进首次渲染路径
最短记忆方式
服务端先画的内容,客户端第一次接手时也得画成同一版。
面试要点
来自 react-hydration-mismatch-interview-question 的面试视角整理。
一句话回答
Hydration mismatch 是 React 在客户端接管服务端 HTML 时发现两边首次渲染结果不一致;常见原因是服务端和客户端使用了不同数据,或者首次渲染依赖了时间、随机值、浏览器环境等不稳定信息。
最稳的回答主线
- SSR 先输出一份 HTML
- 客户端 hydration 时会按组件逻辑再走一遍首次渲染
- 如果这次渲染结果和现有 HTML 对不上,就会出现 mismatch
- 所以关键不是“有没有 SSR”,而是“首屏两边是不是稳定一致”
一个更完整的面试表达
可以这样答:
hydration mismatch 本质上是客户端接管服务端 HTML 时,发现“客户端第一次渲染想要的结果”和“服务端已经输出好的 HTML”对不上。
所以问题的关键不是 SSR 本身,而是两边首屏是否使用了完全一致的输入和渲染路径。只要服务端和客户端首次计算依赖不同,就容易 mismatch。
最常见的成因
- 首次渲染用了
Date.now() - 首次渲染用了
Math.random() - 直接读
window、localStorage、navigator - 服务端和客户端拿到的数据不一致
- 条件分支依赖了浏览器环境
一个典型反例
function Clock() {
return <div>{Date.now()}</div>
}
服务端输出的时间戳和客户端第一次渲染的时间戳天然不同,就很容易出问题。
面试里容易加分的一句
很多 hydration 问题不是出在接管机制本身,而是出在我们把浏览器专属信息或不稳定值提前放进了首屏渲染路径。
怎么规避
- 保证首屏依赖的数据稳定一致
- 浏览器专属逻辑延后到客户端 effect 或客户端组件里
- 不要把随机值、时间戳直接塞进首屏 HTML 生成路径
常见追问
- 哪些值最容易导致 mismatch
- mismatch 会只影响警告,还是会影响体验
- 怎么把只在客户端可用的逻辑延后处理
最短记忆方式
服务端先渲的样子,客户端第一次接手时也得尽量一样。