框架与状态管理 · KNOWLEDGE CHAPTER
K21

React 异步渲染与服务端边界

异步渲染要分清三种边界:资源何时可读、哪些界面一起显示、代码和数据跨服务端与客户端如何流动。Suspense 管等待,错误边界管特定失败,水合管首轮一致,RSC 管执行与模块边界。

框架与状态管理2 道章节练习5 道主练关联

核心模型

异步渲染要分清三种边界:资源何时可读、哪些界面一起显示、代码和数据跨服务端与客户端如何流动。Suspense 管等待,错误边界管特定失败,水合管首轮一致,RSC 管执行与模块边界。

原理与机制

use 读取资源,不接管资源生命周期

React 19 的 use(Promise) 在渲染阶段读取状态:未完成让组件挂起并交给最近 Suspense,已完成取得结果,拒绝交给错误边界。它不是自动请求、缓存、去重与取消工具,资源层必须提供稳定 Promise。客户端 render 每次 fetch 会不断创建新身份,可能重复请求或持续挂起。use 可出现在组件或 Hook 内的条件与循环,但不能因此把普通 Hooks 也移入条件,也不要用普通 try/catch 接住挂起;服务器组件通常优先 async/await。

边界按可理解的展示单元划分

主体、推荐和评论若能独立阅读,应设计不同等待节奏,避免慢评论挡住商品标题;边界切得过碎又会骨架闪动、布局破裂。Suspense 仅响应支持协议的资源,如 lazy、use 或框架数据源,Effect 内 fetch 不会自动触发它。并行启动与预加载决定请求瀑布,不能期待包一个边界就变并行。已有内容重新挂起可借 Transition 暂留,但价格、权限和库存必须标明新鲜度并在提交时重验,不能让旧内容伪装成新状态。

水合依赖共享的确定性输入

SSR 提供先可见的 HTML,客户端第一次渲染应与它一致。时区、随机数、存储主题、无效嵌套或浏览器扩展都会造成 mismatch。解决顺序是统一时间、语言、主题和 ID 快照;只有设备才知道的数据先输出相同占位,再明确更新。suppressHydrationWarning 只处理已理解的局部不可避免差异,不能保证错位内容都会修补。保留服务端 HTML、首轮输入与可恢复错误,跨时区、慢网和存储禁用条件复现,比统一屏蔽警告可靠。

RSC 与 SSR 是两个维度

Server Component 规定某些组件代码在服务端运行,避免相应依赖进入客户端模块图;SSR 规定如何生成初始 HTML,两者可组合。Client Component 仍可能被服务端预渲染,use client 是模块边界,不是“不执行 SSR”的声明。边界放得过高会扩大客户端依赖;服务器内容可作为 children 等传给客户端交互区域,但数据库连接、任意函数和秘密不能任意序列化过去。还要测 RSC 载荷和额外往返,不能只凭 bundle 变小判断整体更快。

错误恢复要同时修复资源身份

错误边界隔离后代渲染等范围内的异常,不自动接住普通 onClick 启动的独立 Promise 或计时器拒绝;这些流程要显式建模可恢复错误,保留输入与重试。Transition Action 与 useActionState 有将抛错交给边界的特定路径,不能套用“异步都不捕获”的旧结论。重置边界但继续读取同一 rejected Promise,会立刻再次失败,应按资源契约失效并创建新尝试。私有缓存必须按请求、用户或租户分域,导航与退出也要阻止旧资源流入新身份。

最小示例

jsx
jsx
import { Suspense, use } from 'react';
function Comments({ resource }) {
  const comments = use(resource);
  return <ul>{comments.map(c => <li key={c.id}>{c.text}</li>)}</ul>;
}
export function Product({ title, commentsPromise }) {
  return <>
    <h1>{title}</h1>
    <Suspense fallback={<p>评论加载中…</p>}>
      <Comments resource={commentsPromise} />
    </Suspense>
  </>;
}

commentsPromise 必须来自支持 Suspense 的稳定资源层或服务器传递,本组件不在 render 创建请求。等待时标题可显示,评论区域使用占位;完成后渲染列表。拒绝需要外层错误边界处理,本例省略其实现而不声称 Suspense 负责错误 UI。切商品需让缓存键和 Promise 对应新资源,并保留一致的首轮 SSR 输入。

环境:React 19 JSX 项目;commentsPromise 来自支持 Suspense 的稳定资源层或服务端,外层错误边界需由应用提供。

核验:已静态审查示例与本章机制一致;未运行此示例,未进行框架或浏览器集成测试。观察结果为待复现的教学预期。

边界与取舍

边界

  • use 不是请求库,Suspense 不监听任意异步任务,边界也不会自动消除数据瀑布。
  • Client Component 不等于纯 CSR;use server 也不是 Server Component 的标记。
  • 错误边界不涵盖所有事件与异步回调;局部重试还需换掉已失败资源,不能只隐藏错误。

取舍

  • 更细等待与失败边界减少局部阻塞,却增加骨架、焦点与恢复设计;按用户任务单元划分。
  • RSC 可减少客户端代码和秘密暴露面,却增加序列化、服务端成本与网络依赖;同时观察多项成本。

口述示范

我把资源生命周期交给缓存或框架,use 只读稳定 Promise,Suspense 按用户能理解的区域控制展示。SSR 要统一首轮快照,RSC 与客户端边界要控制代码和数据体积。错误恢复需要边界与资源同时复位,身份隔离始终优先于缓存复用。

章节练习

练习 1

商品标题快、评论慢、库存失败,如何安排边界和购买入口?

展开检查点
  • 主体与辅助模块分开等待,资源并行启动。
  • 库存失败不能保留看似可用的购买按钮。
  • 局部错误重试同时失效对应资源,保留正确商品与用户身份。
练习 2

SSR 主题与本地存储冲突,团队把根布局全部标 use client,评估替代方案。

展开检查点
  • 统一 Cookie 或传入快照,首轮一致后处理本地偏好。
  • 交互边界下沉,区分预渲染与 RSC 执行。
  • 测 HTML、客户端 JS、RSC 载荷和交互延迟,检查敏感字段。

参考来源与核验边界

以 React 19 系列公开 API 为基础;RSC 底层构建集成接口与框架缓存方案须锁定实际版本,不把框架特性归为 React 自动提供。

内容版本:2026-10-04.2 · 题目和来源 ID 保持原样,本站不将面经标签解释为企业官方出题或高频保证。