Suspense 怎么用?

让组件"等待"的时候有个交代

先说结论:Suspense 为 React 能识别的“未就绪内容”提供 fallback 边界。它最稳定、最通用的用途是代码分割;数据请求是否支持 Suspense 取决于具体框架或数据层。

经典用法:路由懒加载

配合 React.lazy 实现代码分割:

import React, { Suspense } from 'react';

// 这个组件的代码只有在渲染时才会下载
const LazyComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <Suspense fallback={<div>加载中...</div>}>
      <LazyComponent />
    </Suspense>
  );
}

进阶用法:数据请求

部分框架和数据层支持让组件在渲染阶段声明数据依赖,但并不是任意 Promise 或 fetch 都会自动接入 Suspense。

以前:Fetch-on-Render

  1. 组件渲染
  2. useEffect 发请求
  3. Loading
  4. 显示数据

现在:Render-as-you-fetch

  1. 开始渲染
  2. 发现数据没准备好
  3. 抛出一个 Promise
  4. React 捕获 Promise,暂停渲染,显示 Fallback
  5. Promise 完成后,React 重新渲染,显示数据

Streaming SSR

服务端渲染中,Suspense 允许分块流式传输

  • 不用等整个页面的接口都回来
  • 先发 Header、Sidebar
  • 中间内容等接口好了再推过去
  • 首屏更快

注意点

Suspense 可以处理 React 识别的挂起信号,例如懒加载组件或受支持的数据源抛出的 Promise。

普通的 axios.get 放在 useEffect不会触发 Suspense;需要使用明确支持 Suspense 的框架或数据层,并确认其缓存、错误处理和服务端行为。

总结

用法场景
lazy + Suspense路由懒加载
数据请求等待接口
Streaming SSR服务端分块推送

Suspense 就是让等待变得优雅——有东西看,不白屏。