SWR 数据获取
在现代 Web 应用中,数据获取是一个常见的需求。React 本身并没有内置的数据获取机制,因此开发者通常需要借助第三方库来实现这一功能。SWR(Stale-While-Revalidate)是一个由 Vercel 开发的 React 数据获取库,它提供了一种简单而强大的方式来管理数据获取、状态同步和缓存。
什么是 SWR?
SWR 是一种数据获取策略,其核心思想是在数据过期时仍然返回旧数据,同时在后台重新获取最新数据。这种策略能够显著提升用户体验,因为它可以避免用户在等待数据加载时看到空白页面。
SWR 库的名字来源于这种策略的三个关键步骤:
- Stale:返回缓存中的旧数据。
- While:在后台重新获取最新数据。
- Revalidate:用新数据替换旧数据。
安装 SWR
要开始使用 SWR,首先需要安装它。你可以通过 npm 或 yarn 来安装:
npm install swr
或者
yarn add swr
基本用法
SWR 的核心是一个名为 useSWR
的 React Hook。它接受两个参数:
- key:一个唯一的字符串,用于标识要获取的数据。
- fetcher:一个异步函数,用于实际获取数据。
以下是一个简单的示例,展示如何使用 useSWR
获取用户数据:
import useSWR from 'swr';
const fetcher = (url) => fetch(url).then((res) => res.json());
function UserProfile({ userId }) {
const { data, error } = useSWR(`/api/user/${userId}`, fetcher);
if (error) return <div>Failed to load user</div>;
if (!data) return <div>Loading...</div>;
return (
<div>
<h1>{data.name}</h1>
<p>{data.email}</p>
</div>
);
}
在这个示例中,useSWR
会根据 userId
动态生成一个唯一的 key,并使用 fetcher
函数从 /api/user/${userId}
获取数据。如果数据尚未加载完成,data
将为 undefined
,此时我们可以显示一个加载提示。如果数据加载失败,error
将被设置,我们可以显示一个错误提示。
自动重新验证
SWR 的一个强大功能是自动重新验证。默认情况下,SWR 会在以下情况下重新获取数据:
- 当组件重新挂载时。
- 当浏览器窗口重新获得焦点时。
- 当网络重新连接时。
这种行为确保了用户始终看到最新的数据,而不需要手动刷新页面。
缓存与状态同步
SWR 会自动缓存获取的数据,并在多个组件之间共享这些数据。这意味着如果你在多个地方使用相同的 key 来获取数据,SWR 只会发送一次请求,并在所有组件之间共享结果。
例如,假设你在两个不同的组件中使用相同的 key 获取用户数据:
function UserProfile({ userId }) {
const { data } = useSWR(`/api/user/${userId}`, fetcher);
// ...
}
function UserAvatar({ userId }) {
const { data } = useSWR(`/api/user/${userId}`, fetcher);
// ...
}
在这种情况下,SWR 只会发送一次请求,并在 UserProfile
和 UserAvatar
之间共享数据。
实际应用场景
1. 分页数据加载
SWR 非常适合用于分页数据加载。你可以使用 useSWR
来获取分页数据,并在用户翻页时自动更新数据。
function PaginatedPosts({ page }) {
const { data } = useSWR(`/api/posts?page=${page}`, fetcher);
if (!data) return <div>Loading...</div>;
return (
<ul>
{data.posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
2. 实时数据更新
SWR 还可以与 WebSocket 或其他实时数据源结合使用,以实现实时数据更新。你可以使用 mutate
函数手动更新缓存中的数据。
import useSWR, { mutate } from 'swr';
function RealTimeStockPrice({ stockId }) {
const { data } = useSWR(`/api/stock/${stockId}`, fetcher);
// 假设我们有一个 WebSocket 连接,用于接收实时股票价格更新
useEffect(() => {
const ws = new WebSocket('wss://stock-prices.com');
ws.onmessage = (event) => {
const newPrice = JSON.parse(event.data);
mutate(`/api/stock/${stockId}`, newPrice, false);
};
return () => ws.close();
}, [stockId]);
if (!data) return <div>Loading...</div>;
return <div>Current Price: {data.price}</div>;
}
在这个示例中,我们使用 WebSocket 接收实时股票价格更新,并使用 mutate
函数手动更新缓存中的数据。
总结
SWR 是一个功能强大且易于使用的数据获取库,特别适合用于 React 应用。它通过自动重新验证、缓存管理和状态同步,极大地简化了数据获取的复杂性。无论你是构建一个简单的用户界面,还是一个复杂的实时应用,SWR 都能帮助你更高效地管理数据。
附加资源与练习
- SWR 官方文档
- 练习:尝试使用 SWR 构建一个简单的博客应用,实现分页加载文章和实时评论更新。
如果你对 SWR 的更多高级功能感兴趣,可以查看官方文档中的 高级用法 部分。