next.js 16 水合问题
它用一种特殊的 JSON 格式,完整记录了整棵组件树的结构和所有服务器组件渲染后的最终结果。// 服务器组件 (Server Component)return (<h1>文章标题</h1> {/* 静态内容 */}<LikeButton /> {/* 客户端组件 'use client' */}</div>对于这段代码,服务端绝对不会把的 JS 发给浏览器,但它会在里写下这样一份“结构描述说明书”
你提出了一个非常深刻且直击核心的问题!你提到的 use client 意味着我们现在讨论的是 Next.js 的 App Router(RSC 架构)。
你的直觉完全正确:服务器确实没有把服务器组件(Server Components)的 JS 代码发给浏览器,浏览器手里只有客户端组件(Client Components)的 JS Chunks。
那为什么两者的虚拟 DOM 树还能对得上,不会触发水合错误呢?
因为 Next.js 在这里玩了一个极其硬核的“魔术”:服务端传给浏览器的,除了 HTML,还有一份绝密的数据文件——RSC Payload(React 服务端组件载荷)。
📦 浏览器收到的到底是什么?
当访问一个包含服务器组件和客户端组件的页面时,Next.js 服务端会并行生成并发送三样东西给浏览器:
- HTML 结构:供浏览器快速渲染,让用户肉眼看到网页。
- JS Chunks:仅仅包含带有
"use client"的客户端组件的交互逻辑。 - RSC Payload:这是一串特殊的、序列化的文本数据(你可以把它理解为一个超级线索文件)。
什么是 RSC Payload?
它用一种特殊的 JSON 格式,完整记录了整棵组件树的结构和所有服务器组件渲染后的最终结果。
举个例子,假设你有一个服务器组件,里面包裹了一个客户端组件:
// 服务器组件 (Server Component)
export default function ArticlePage() {
return (
<div className="container">
<h1>文章标题</h1> {/* 静态内容 */}
<LikeButton /> {/* 客户端组件 'use client' */}
</div>
)
}
对于这段代码,服务端绝对不会把 ArticlePage 的 JS 发给浏览器,但它会在 RSC Payload 里写下这样一份“结构描述说明书”:
“报告浏览器 React 运行时:整棵树的根是一个
div,类名叫container;它下面有一个h1,里面的文本是‘文章标题’;再往下是一个占位符,对应的是客户端组件LikeButton,这个组件的 JS 代码在chunk-abc123.js里。”
🔄 客户端 React 运行时是如何构建虚拟 DOM 的?
当浏览器的 React 运行时(Runtime)启动时,它并不是单纯地去运行那些 JS Chunks,而是把 JS Chunks 和 RSC Payload 结合起来看:
- React 读取 RSC Payload 说明书。
- 看到
div和h1,React 说:“知道了,这是服务器组件留下的静态结构。” 于是直接在内存的虚拟 DOM 树中画出div和h1。 - 看到
LikeButton占位符,React 说:“噢,这里需要客户端交互。” 于是它去翻看下载好的 JS Chunks,把LikeButton的核心逻辑、事件监听器(onClick)拿过来,插进刚刚构建的虚拟 DOM 树的对应位置。
最终结果:React 仅仅利用“RSC Payload 说明书”+“客户端 JS Chunks”,就在浏览器内存中完美复刻出了完整的虚拟 DOM 树!
因为这棵虚拟 DOM 树的骨架完全是按照服务器给的说明书(RSC Payload)画出来的,所以它和服务器生成的 HTML 结构 100% 严丝合缝。水合顺利通过,完全不会报错!
📊 架构可视化
我们可以通过下面的对比图,看清 React 客户端运行时是如何利用两股数据合流,完美还原虚拟 DOM 的:
💡 总结
你之所以产生怀疑,是因为在传统 React 单页应用中,“代码 (JS)”等于“结构 (DOM)”。
但在 Next.js 的 RSC 架构中,“结构”已经和服务端组件的代码分离了。服务器组件的代码留在了后端,它的“结构”变成了 RSC Payload 发给了前端;只有客户端组件的代码才作为 JS Chunks 发给前端。
React 运行时聪明地利用 RSC Payload 织出了整棵树的皮肤,再用 JS Chunks 激活了局部的器官,从而实现了完美的、无报错的水合。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)