RSC 的服务器/客户端边界:不是“选 SSR 还是 CSR”,而是“每个区域单独决定”
2026 年,React Server Components 已经是新 React 应用的推荐方案,Next.js 的支持成熟,Remix 等元框架也在跟进。但很多团队在落地时仍然把它理解成“SSR 的升级版”,结果边界划错,复杂度不降反升。
RSC 的核心是把组件树拆成服务器模块图和客户端模块图。Server Component 的代码只留在服务器上,不进入浏览器包;Client Component 的代码在服务器和浏览器两边都会运行。服务器渲染 Server Component 树,产出一份 RSC Payload,里面带着对 Client Component 的引用和序列化后的 props。客户端图通过 Payload 拿到这些引用,不直接 import 服务器图。
“Server Component”描述的是组件代码在哪里运行、是否发到浏览器;“服务器渲染”描述的是 HTML 怎么产生。一个 Client Component 在直接访问时也会在服务器上渲染成 HTML,然后在浏览器里 hydration;它仍然是 Client Component,只是参与了服务器渲染。把这两个概念混在一起,就会得出“用了 RSC 就没有 hydration”这类错误结论。
边界划错最常见的方式是“在 Server Component 里想用客户端状态”。Server Component 不能使用 useState、useEffect 和浏览器 API。正确的做法是把需要交互的部分下沉成 Client Component,用 props 接收服务器取到的数据。另一个常见错误是把不可序列化的值——函数、类实例、Symbol——从 Server Component 传给 Client Component。RSC Payload 需要序列化,边界上的 props 必须是可序列化的。
一个比较实用的心智模型是“每个区域单独决定”:页面的这一块是纯数据展示,就留在 Server Component;那一块需要用户交互,就标记为 Client Component 并尽可能下沉到叶子。不要试图整页统一成一种模式,也不要因为“RSC 是新东西”就把所有东西都标成 Server Component 然后在里面硬塞客户端逻辑。
RSC 的收益是真实的:重型依赖不再进入客户端包,首屏 JS 更小,数据获取靠近服务端。但代价是序列化边界的心智负担和调试复杂度的上升。它适合内容型页面、数据展示密集的界面;对于交互密集的后台,把所有东西都标 "use client" 等于放弃 RSC 的收益,但至少不会引入边界 bug。先画清楚哪些区域需要交互,再决定边界放在哪里,比先选“全 RSC”或“全客户端”更可靠。
- 点赞
- 收藏
- 关注作者
评论(0)