跳到主要内容

SWR 数据获取

在现代 Web 应用中,数据获取是一个常见的需求。React 本身并没有内置的数据获取机制,因此开发者通常需要借助第三方库来实现这一功能。SWR(Stale-While-Revalidate)是一个由 Vercel 开发的 React 数据获取库,它提供了一种简单而强大的方式来管理数据获取、状态同步和缓存。

什么是 SWR?

SWR 是一种数据获取策略,其核心思想是在数据过期时仍然返回旧数据,同时在后台重新获取最新数据。这种策略能够显著提升用户体验,因为它可以避免用户在等待数据加载时看到空白页面。

SWR 库的名字来源于这种策略的三个关键步骤:

  1. Stale:返回缓存中的旧数据。
  2. While:在后台重新获取最新数据。
  3. Revalidate:用新数据替换旧数据。

安装 SWR

要开始使用 SWR,首先需要安装它。你可以通过 npm 或 yarn 来安装:

bash
npm install swr

或者

bash
yarn add swr

基本用法

SWR 的核心是一个名为 useSWR 的 React Hook。它接受两个参数:

  1. key:一个唯一的字符串,用于标识要获取的数据。
  2. fetcher:一个异步函数,用于实际获取数据。

以下是一个简单的示例,展示如何使用 useSWR 获取用户数据:

jsx
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 会在以下情况下重新获取数据:

  1. 当组件重新挂载时。
  2. 当浏览器窗口重新获得焦点时。
  3. 当网络重新连接时。

这种行为确保了用户始终看到最新的数据,而不需要手动刷新页面。

缓存与状态同步

SWR 会自动缓存获取的数据,并在多个组件之间共享这些数据。这意味着如果你在多个地方使用相同的 key 来获取数据,SWR 只会发送一次请求,并在所有组件之间共享结果。

例如,假设你在两个不同的组件中使用相同的 key 获取用户数据:

jsx
function UserProfile({ userId }) {
const { data } = useSWR(`/api/user/${userId}`, fetcher);
// ...
}

function UserAvatar({ userId }) {
const { data } = useSWR(`/api/user/${userId}`, fetcher);
// ...
}

在这种情况下,SWR 只会发送一次请求,并在 UserProfileUserAvatar 之间共享数据。

实际应用场景

1. 分页数据加载

SWR 非常适合用于分页数据加载。你可以使用 useSWR 来获取分页数据,并在用户翻页时自动更新数据。

jsx
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 函数手动更新缓存中的数据。

jsx
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 的更多高级功能感兴趣,可以查看官方文档中的 高级用法 部分。