React 哲学之 Suspense

5 阅读1分钟

二、两种典型用法

1. 与 lazy 配合:代码分割

const Other = React.lazy(() => import('./Other'));

function App() {
  return (
    <Suspense fallback={<div>加载中…</div>}>
      <Other />
    </Suspense>
  );
}

这里「异步」的是模块加载。子组件加载完成前,会显示 fallback。

2. 与「可挂起」的数据请求配合

当数据层支持 Suspense(例如在 render 里读「未就绪」的数据会 throw Promise)时,可以这样写:

function Profile() {
  const user = use(getUser()); // 未就绪时内部 throw Promise
  return <div>{user.name}</div>;
}

<Suspense fallback={<Skeleton />}>
  <Profile />
</Suspense>

此时「异步」的是数据。React 会等 Promise resolve 后重新渲染该子树。


三、设计哲学小结

含义
声明式加载状态父级用 Suspense 声明「这里有一块异步」,而不是在子组件里 if (loading) return ...
与数据/代码解耦子组件只表达「需要什么」,不负责写 loading/error UI,便于复用与组合
为并发渲染铺路与 Transition、useDeferredValue 等配合,让 React 能调度优先级、减少卡顿感

四、使用注意

  • fallback 要有:每个 Suspense 都应提供 fallback,否则会报错或行为异常。
  • 边界放在哪:边界越靠上,覆盖的异步范围越大,但 fallback 持续时间可能更长;通常按「路由」或「大区块」划分。
  • 与 Error Boundary 搭配:Suspense 只接「挂起」,不接错误;请求失败仍要由 Error Boundary 或上层 try/catch 处理。

总结

  • Suspense 把「这里在等异步结果」从子组件里抽离出来,由父级用 fallback 统一表达,符合 React 的声明式哲学。
  • 既可用于代码分割(lazy),也可用于数据请求(需数据层支持「挂起」协议)。
  • 用好 Suspense,能让加载状态更清晰、更易与并发特性结合,为后续的 React 演进留足空间。

若对你有用,欢迎点赞、收藏;你有在项目里用 Suspense 做数据加载的实践,也欢迎在评论区分享。