Suspense
是 React 提供的一个用于处理异步渲染和加载状态的机制,可以让你在组件等待数据或资源准备好的时候显示一个“备用 UI”(fallback),从而改善用户体验。
1. 什么是 Suspense
通常在 React 中,我们需要加载一些异步数据或者异步组件,比如:
- 请求接口数据
- 按需动态导入组件(代码分割)
- 等待图片或资源加载
以前你可能会写成这样:
function App() {
const [loading, setLoading] = React.useState(true);
const [data, setData] = React.useState(null);
React.useEffect(() => {
fetch("/api/data")
.then((res) => res.json())
.then((data) => {
setData(data);
setLoading(false);
});
}, []);
if (loading) return <div>Loading...</div>;
return <div>{data.title}</div>;
}
这样做麻烦且不优雅,React 18 提供的 Suspense
可以简化这类逻辑,把“等待时显示什么”交给 Suspense 统一处理。
2. 基本用法
Suspense
的核心是:
<Suspense fallback={<Loading />}>
{/* 这里放需要等待的组件 */}
</Suspense>
fallback
:在子组件还没准备好时显示的内容(例如 Loading)。- 子组件完成加载后,会自动渲染真实内容。
例子:懒加载组件
import React, { Suspense } from "react";
// React.lazy 动态导入组件
const LazyComponent = React.lazy(() => import("./MyComponent"));
function App() {
return (
<div>
<h1>主页</h1>
<Suspense fallback={<div>加载中...</div>}>
<LazyComponent />
</Suspense>
</div>
);
}
- 当
MyComponent
还没加载完成时,显示“加载中...” - 加载完成后,自动显示组件内容
3. Suspense 的场景
- 懒加载组件(React.lazy)
适合按需加载页面或组件,避免首屏加载过大。 数据加载(React 18 + React 服务器组件 + React Query)
- 配合 React 18 的 concurrent mode 或 React Query 的
useSuspenseQuery
可以在数据请求时触发 Suspense
- 配合 React 18 的 concurrent mode 或 React Query 的
- 流式渲染(Streaming)
服务器可以先返回部分 HTML,后续数据到达时再“填充”,提高首屏速度。
4. 数据加载示例(React 18 + React Query)
import { Suspense } from "react";
import { useSuspenseQuery } from "@tanstack/react-query";
function User() {
const { data } = useSuspenseQuery({
queryKey: ["user"],
queryFn: () => fetch("/api/user").then((res) => res.json()),
});
return <div>用户名:{data.name}</div>;
}
function App() {
return (
<Suspense fallback={<div>用户信息加载中...</div>}>
<User />
</Suspense>
);
}
- 请求接口数据时,会自动触发 Suspense 的 fallback。
- 数据返回后,Suspense 会渲染真实组件。
5. 注意点
Suspense
本身不处理数据获取,只是等待 子组件触发的 Promise。- 配合
React.lazy
使用最简单;要用在数据加载上,需要结合 React 18 + Concurrent Features 或一些库(如 React Query)。 fallback
是必填的,不然加载期间不会显示任何内容。
6. 总结
Suspense
的核心作用:
- 统一处理异步加载的过渡状态
- 简化 Loading 逻辑
- 提升用户体验
公式理解:
<Suspense fallback={加载状态}>
需要等待的组件
</Suspense>