菜单

React 服务端组件

相关源文件

本文档解释了React服务器组件(React Server Components,简称RSC),这是一种React架构模式,允许组件仅在服务器上运行。与传统的服务器端渲染(SSR)不同,SSR在将HTML发送到客户端之前在服务器上渲染组件一次,而React服务器组件仅在服务器上执行并将其结果流式传输到客户端。有关React传统服务器端渲染的信息,请参阅服务器端渲染

概述

React服务器组件使开发人员能够构建应用程序,其中一些组件仅在服务器上运行,而另一些则在客户端上运行。这种方法提供了几个优点:

  • 仅限服务器端代码:访问数据库、文件系统和其他服务器资源,而无需在客户端代码中暴露
  • 减小打包大小:服务器组件不包含在发送到客户端的JavaScript中
  • 自动代码分割:客户端组件会自动进行代码分割
  • 零打包大小依赖:仅限服务器端的依赖项不会影响客户端打包大小
  • 完全访问服务器:无需中间API即可直接访问数据库或文件系统

Flight协议(React用于服务器组件的流式传输格式)将服务器组件的输出传输到客户端,然后客户端将其与客户端渲染的组件集成。

来源

架构

React服务器组件引入了React应用程序结构和渲染方式的根本性转变,将组件分为三类:

组件架构图

来源

组件类型

  1. 服务器组件:仅在服务器上运行。可以访问服务器资源(数据库、文件系统等)。不能使用React Hooks或浏览器API。

  2. 客户端组件:仅在客户端上运行。可以使用React Hooks、浏览器API和交互功能。在文件顶部通过'use client'指令标记。

  3. 共享组件:在两种环境中运行。仅限于在服务器和客户端都可用的功能。

指令方法确保了组件类型之间的清晰界限

来源

服务器组件实现

服务器组件是React服务器组件架构中的默认组件类型。它们在服务器上执行,其输出被序列化并发送到客户端。

主要特点

  • 可以直接访问服务器端资源(数据库、文件系统)
  • 不能使用React Hooks或浏览器API
  • 不能在请求之间维护状态
  • 子组件可以是服务器组件或客户端组件
  • 从父组件接收的props只能包含可JSON序列化的数据或引用

执行流程

来源

服务器组件序列化

服务器组件由Flight服务器处理,并转换为可发送到客户端的序列化格式

  1. 组件树被递归遍历
  2. 服务器组件执行,产生其渲染输出
  3. 客户端组件引用被保留,不执行
  4. 渲染输出被序列化为Flight协议格式
  5. 结果流式传输到客户端

来源

客户端组件集成

客户端组件在浏览器中运行,可以利用React的完整交互功能集。它们由服务器组件引用,但在到达客户端之前不会执行。

识别客户端组件

客户端组件在文件顶部通过'use client'指令标记

在构建过程中,客户端组件会:

  1. 与服务器组件分开打包
  2. 分配唯一的标识符以供引用
  3. 在客户端需要时可用以加载

来源

客户端引用处理

来源

Flight 协议

Flight协议是允许服务器组件与客户端通信的传输机制。它以专门的格式序列化组件树、数据和引用。

序列化格式

Flight协议使用特殊编码处理各种数据类型

数据类型序列化方法描述
原始JS值直接JSON编码字符串、数字、布尔值、null
对象和数组带引用跟踪的JSON编码对象被序列化,并处理循环引用
React元素特殊编码格式元素与其类型、props和children一起传输
客户端组件引用ID仅发送ID,实际组件在客户端加载
Promises占位符 + 异步解析Promise作为占位符发送,然后发送解析值
分块传输数据以可用时分块流式传输
服务器函数服务器引用ID可以从客户端调用回服务器的函数

来源

数据块结构

Flight协议以数据块形式传输数据,每个数据块都有特定的结构

来源

服务器-客户端交互

React服务器组件通过专用机制实现服务器和客户端之间的双向通信。

服务器 → 客户端流程

  1. 服务器组件在服务器上执行
  2. 输出使用Flight协议进行序列化
  3. 序列化数据流式传输到客户端
  4. 客户端反序列化数据
  5. 组件树被重建,客户端组件在客户端渲染

来源

客户端 → 服务器流程(服务器动作)

服务器组件可以导出函数,这些函数可以从客户端调用,称为服务器引用。

来源

Suspense和流式传输

React服务器组件与Suspense集成,以支持异步渲染和流式传输

Suspense集成

当服务器组件挂起时

  1. 该组件的渲染暂停
  2. React继续渲染树的其他部分
  3. 当挂起的数据可用时,渲染恢复
  4. 已解析的组件流式传输到客户端
  5. 客户端使用新可用的组件更新UI

来源

错误处理

React服务器组件内置了服务器端和客户端错误处理机制

服务器端错误处理

当服务器组件渲染期间发生错误时

  1. 错误在最近的错误边界处捕获
  2. 错误信息被序列化(生产环境中会移除敏感细节)
  3. 错误流式传输到客户端
  4. 客户端错误边界可以捕获并显示错误

来源

客户端错误处理

客户端组件渲染期间的错误由标准React错误边界处理,从而实现优雅降级和回退UI。

来源

使用RSC构建

React服务器组件通常需要构建系统集成来正确处理服务器和客户端代码的分离。

Webpack 集成

最常见的集成是使用webpack和专用插件

构建过程

  1. 通过指令识别客户端和服务器组件
  2. 单独打包客户端组件
  3. 创建客户端和服务器代码之间的引用映射
  4. 优化代码分割和懒加载

来源

性能考量

React服务器组件通过多种机制提供性能优势

打包大小优化

  • 服务器组件不包含在客户端JavaScript包中
  • 只有输出(通常比代码小得多)发送到客户端
  • 仅在服务器组件中使用的依赖项不影响客户端包大小

流式传输和渐进渲染

  • 初始内容可以快速交付,同时复杂部分加载
  • Suspense边界允许内容的增量加载
  • 网络瀑布可以在服务器上处理,而不是在客户端上顺序发生

自动代码分割

  • 客户端组件会自动进行代码分割
  • 只为页面中实际使用的客户端组件加载JavaScript
  • 代码分割自然发生,无需开发人员手动操作

来源

限制和注意事项

服务器组件限制

  • 不能使用React Hooks(useStateuseEffect等)
  • 不能访问浏览器特定的API
  • 不能在请求之间维护状态
  • 不能直接导入到客户端组件中

客户端组件限制

  • 不能直接导入服务器组件
  • 从服务器到客户端的Props必须是可序列化的
  • 客户端组件不能是异步函数

服务器引用限制

  • 参数和返回值必须是可序列化的
  • 错误处理需要特殊考虑

来源

结论

React服务器组件代表了React在架构上的重大进步,使开发人员能够构建智能地在服务器和客户端之间分配渲染职责的应用程序。通过利用两种环境的优势,RSC提供了一种更高效、更具可扩展性、并通过减少JavaScript负载和加快初始渲染来提供更好用户体验的应用程序构建途径。