You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React与Vue中"hydration mismatch"是什么意思?

关于React与Vue中"Hydration Mismatch"的含义解析

我在同时折腾Vue和React开发时也常踩这个坑,刚好给你掰扯清楚这俩框架里这个术语到底啥意思:

React中的Hydration Mismatch

先讲React这边:当你用服务端渲染(SSR)或者静态站点生成(SSG)的时候,服务端会先把React组件渲染成静态的HTML字符串,发给浏览器。浏览器拿到这串HTML后,会做一个叫「hydration(水合)」的操作——简单说就是把静态的HTML和客户端的React组件关联起来,让静态页面拥有交互能力。

如果服务端输出的HTML结构、属性、文本内容,和客户端React组件首次渲染出来的结果不一样,就会触发hydration mismatch(水合不匹配)。

举几个常见的触发场景:

  • 服务端渲染时用了new Date()生成当前时间,客户端hydrate时时间已经变了,导致文本内容对不上;
  • 服务端渲染时某个组件的条件渲染依赖服务端特有的变量(比如只有服务端能拿到的用户信息),客户端没有这个变量,渲染出的DOM结构和服务端的不一样;
  • 服务端渲染的元素属性(比如class或者id)和客户端渲染的不一致。

碰到这个问题时,React控制台会抛出明确的警告,严重的话可能导致交互失效(比如按钮点不动),或者页面出现奇怪的渲染bug(比如元素突然移位、文本乱跳)。

Vue中的Hydration Mismatch

Vue这边的逻辑其实和React核心一致:当你用Vue SSR或者Nuxt.js这类框架做预渲染时,服务端先生成静态HTML,客户端挂载Vue应用时会进行hydration,把静态DOM转换成可交互的Vue组件。

如果服务端预渲染的DOM结构、内容,和客户端首次渲染的结果不匹配,就会出现hydration mismatch

Vue里常见的触发场景:

  • 用了process.server(Nuxt里的变量)在服务端渲染不同的内容,客户端没有这个变量,导致渲染结果不一致;
  • 服务端渲染时获取的数据和客户端hydrate时重新请求的数据不一样,比如接口返回的内容有更新;
  • 组件里用了客户端特有的API(比如window对象)在服务端渲染时返回了不同的结果,客户端渲染时又变了。

Vue碰到这个问题时,控制台会弹出类似「Hydration node mismatch」的警告,严重的话可能导致组件状态异常,部分交互无法正常工作,甚至页面会重新渲染整个组件树,直接浪费了SSR带来的性能优势。

核心总结

其实俩框架里这个问题的本质是完全一样的:服务端预渲染的静态DOM,和客户端首次渲染的DOM存在不一致,只是各自的报错提示细节、部分场景的触发条件略有不同而已。

内容的提问来源于stack exchange,提问作者brillout

火山引擎 最新活动