
SWR 是 vervel 公司开源的一个 npm 包,也是由 Next.js(React 框架)背后的同一团队创建。SWR 是一个 React Hook,用来简化 React 项目中获取远程数据的逻辑。
概述
对于 SWR 的由来及缓存策略,官方的介绍非常浅显易懂。
❝
“SWR” 这个名字来自于 stale-while-revalidate:一种由 HTTP RFC 5861 推广的 HTTP 缓存失效策略。这种策略首先从缓存中返回数据(过期的),同时发送 fetch 请求(重新验证),最后得到最新数据。
❞
需要注意的是,SWR 本身并不提供请求数据能力,需要外部传入(通过 fetcher
函数)。SWR 主要用于解决数据请求时、数据请求过程中的优化处理,包括(但不限于):
-
请求响应数据的缓存能力,避免重复请求数据 -
请求错误时的重试机制 -
定期获取数据及数据校验机制 -
页面重新聚焦时的数据验证机制
快速入门
创建项目
# 基于 React TypeScript 模板,创建的项目位于 swr-demos 目录
$ pnpm create vite swr-demos --template react-ts
# 进入安装依赖,并启动项目
$ cd swr-demos
$ pnpm install
$ pnpm run dev
VITE v5.0.0 ready in 1326 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h + enter to show help
浏览器打开 http://localhost:5173/ 地址,看在如下界面,表示项目启动成功。

安装 SWR
$ pnpm install swr
使用 SWR
首先,需要创建一个 fetcher
函数,这个函数会传递给 SWR,用于提供实际的数据请求能力,我们这里就使用 Fetch API 了:
const fetcher = (...args) => fetch(...args).then((res) => res.json())
fetcher
函数的格式是固定的——是一个封装实际请求的包装函数。
接下来创建一个 src/Profile.tsx
组件。
import useSWR from "swr";
const fetcher = (...args: any[]) => fetch(...args as [string]).then((res) => res.json())
export default function Profile() {
const { data, error, isLoading } = useSWR("https://jsonplaceholder.typicode.com/users/1", fetcher)
if (error) return <div>failed to load</div>
if (isLoading) return <div>loading...</div>
// 渲染数据
return <div>hello, {data.name}!</div>
}
useSWR()
Hook 常用的返回数据有:data
、error
和 isLoading
,分别表示响应数据、是否发生错误,以及是否正在加载中。满足了确定当前的请求状态(“loading”、“ready”或“error”),并返回相应的 UI。
然后,在 src/App.tsx
中引入。
import Profile from './Profile'
function App() {
return <>
{/* ... */}
<Profile />
</>
}
会看到下面的效果,说明成功了。

多参数传入
useSWR()
的第一个参数会被原样传递给 fetcher
函数。因此,下面两个写法是等价的:
useSWR('/api/user', url => fetcher(url))
useSWR('/api/user', fetcher)
原理上,**useSWR**
** 的第一个参数会作为 SWR key,作为请求和数据缓存的唯一标识,后续再有同样的请求发生时,会直接从缓存里拿到数据,而无需重复请求。**
但我们的请求通常会面临多个参数的传入,这个时候,有 2 种支持方式。
-
将字符串传入改用数组传入 -
将字符串传入改用对象传入
改用数组传入的案例如下:
const fetcher = ([url, userId]: [string, number]) => {
return fetch(`${url}/${userId}`).then((res) => res.json())
}
改用数组传入的案例如下:
type Args = { url: string, args: { userId: number } }
const fetcher = ({ url, args: { userId } }: Args) => {
return fetch(`${url}/${userId}`).then((res) => res.json())
}
上面两种方式是等价的。也就是说传递给 useSWR()
的第一个参数会透传给 fetcher
使用。
不同类型的 fetcher
之前的案例中,我们是使用的 Fetch API 获取请求数据。你可以使用任何库来处理数据请求,因为 SWR 是与具体库无关的。
unfetch
developit/unfetch[1] 是 Fetch API 的极简 polyfill 实现:
import fetch from 'unfetch'
const fetcher = url => fetch(url).then(r => r.json())
function App () {
const { data, error } = useSWR('/api/data', fetcher)
// ...
}
❝
Next.js 中已经内置 Fetch API 支持,所以无需要额外引入。
❞
Axios
import axios from 'axios'
const fetcher = url => axios.get(url).then(res => res.data)
function App () {
const { data, error } = useSWR('/api/data', fetcher)
// ...
}
甚至 GraphQL 也支持[2]。
总结
本文介绍了 SWR 库的基本使用方法,其默认配置就能最大程度的提升我们的请求性能了。
其他高级话题,大家可以通过阅读官方文档了解,比如:
-
自动重新请求[3] -
条件请求[4] -
数据预请求[5] -
配合 Next.js 中的与渲染方案[6](SSG,SSR)
感谢阅读,Happy Coding!
参考资料
developit/unfetch: https://github.com/developit/unfetch
[2]
GraphQL 也支持: https://swr.vercel.app/zh-CN/docs/data-fetching#graphql
[3]
自动重新请求: https://swr.vercel.app/zh-CN/docs/revalidation
[4]
条件请求: https://swr.vercel.app/zh-CN/docs/conditional-fetching
[5]
数据预请求: https://swr.vercel.app/zh-CN/docs/prefetching
[6]
配合 Next.js 中的与渲染方案: https://swr.vercel.app/zh-CN/docs/with-nextjs
原文始发于微信公众号(写代码的宝哥):SWR:一个用来简化数据获取的 React Hook
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/243711.html