<Suspense>
<Suspense> 允许在子组件完成加载前展示一个 fallback。
<Suspense fallback={<Loading />}>
<SomeComponent />
</Suspense>
参数
- children:真正的 UI 渲染内容。
- 如果 children 在渲染中被挂起,Suspense 边界将会渲染 fallback。
- fallback:真正的 UI 未渲染完成时代替其渲染的备用 UI,它可以是任何有效的 React 节点。
- fallback 通常是一个轻量的占位符,例如表示加载中的图标或者骨架屏。
- 当 children 被挂起时 ,Suspense 将自动切换至渲染 fallback;当数据准备好时,又会自动切换至渲染 children。
- 如果 fallback 在渲染中被挂起,那么将自动激活最近的 Suspense 边界。
注意
- 在组件首次挂载前,如果组件被挂起,那么 React 将不会保留其任何状态。当组件完成加载后,React 将从头开始重新尝试渲染被挂起的组件树。
- 如果 Suspense 正在展示 React 组件树中的内容,那么当再次被挂起时,除非导致此处更新是由 startTransition 或 useDeferredValue 引起,否则 Suspense 将展示 fallback。
- 如果 React 需要隐藏被再次挂起的可见内容,它将清理内容树中的 layout effect。当内容可以被再次展示时,React 将重新触发 layout effect。这确保了测量 DOM 布局的 effect 不会在内容不可见时运行。
- React 带有内置优化,例如 流式服务器渲染(Streaming Server Rendering) 和 Selective Hydration,它们已经与 Suspense 集成。参见 架构概述 并观看 技术讲座 以了解更多。
用法
当内容正在加载时显示 fallback
你可以使用 Suspense 边界包裹你应用的任何部分:
<Suspense fallback={<Loading />}>
<Albums />
</Suspense>
React 将展示 fallback 直到 children 需要的所有代码和数据都加载完成。
在下面的例子中,Albums 组件在获取专辑列表时被 挂起。在它准备好渲染前,Albums 祖先组件中距离其最近的 Suspense 将展示 fallback —— 即 Loading 组件。当数据加载完成时,React 会隐藏 Loading fallback 并渲染带有数据的 Albums 组件。
import { Suspense } from 'react'
import Albums from './Albums.js'
export default function ArtistPage({ artist }) {
return (
<>
<h1>{artist.name}</h1>
<Suspense fallback={<Loading />}>
<Albums artistId={artist.id} />
</Suspense>
</>
)
}
function Loading() {
return <h2>🌀 Loading...</h2>
}
注意
只有启用了 Suspense 的数据源才会激活 Suspense 组件,它们包括:
- 支持 Suspense 的框架如 Relay 和 Next.js。
- 使用 lazy 懒加载组件代码。
- 使用 use 读取 Promise 的值。
- Suspense 无法 检测在 Effect 或事件处理程序中获取数据的情况。
在上面的 Albums 组件中,正确的数据加载方法取决于你使用的框架。如果你使用了支持 Suspense 的框架,你会在其数据获取文档中找到详细信息。
目前尚不支持在不使用固定框架的情况下进行启用 Suspense 的数据获取。实现支持 Suspense 数据源的要求是不稳定的,也没有文档。React 将在未来的版本中发布官方 API,用于与 Suspense 集成 数据源。
逐步加载内容
<Suspense fallback={<BigSpinner />}>
<Biography />
<Suspense fallback={<AlbumsGlimmer />}>
<Panel>
<Albums />
</Panel>
</Suspense>
</Suspense>