SWR:一个用来简化数据获取的 React Hook

SWR:一个用来简化数据获取的 React Hook

SWR 是 vervel 公司开源的一个 npm 包,也是由 Next.js(React 框架)背后的同一团队创建。SWR 是一个 React Hook,用来简化 React 项目中获取远程数据的逻辑。

概述

对于 SWR 的由来及缓存策略,官方的介绍非常浅显易懂。

“SWR” 这个名字来自于 stale-while-revalidate:一种由 HTTP RFC 5861 推广的 HTTP 缓存失效策略。这种策略首先从缓存中返回数据(过期的),同时发送 fetch 请求(重新验证),最后得到最新数据。

需要注意的是,SWR 本身并不提供请求数据能力,需要外部传入(通过 fetcher 函数)。SWR 主要用于解决数据请求时、数据请求过程中的优化处理,包括(但不限于):

  1. 请求响应数据的缓存能力,避免重复请求数据
  2. 请求错误时的重试机制
  3. 定期获取数据及数据校验机制
  4. 页面重新聚焦时的数据验证机制

快速入门

创建项目

# 基于 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:一个用来简化数据获取的 React Hook

安装 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 常用的返回数据有:dataerrorisLoading,分别表示响应数据、是否发生错误,以及是否正在加载中。满足了确定当前的请求状态(“loading”、“ready”或“error”),并返回相应的 UI。

然后,在 src/App.tsx 中引入。

import Profile from './Profile'

function App({
  return <>
    {/* ... */}
    <Profile />
  </>

}

会看到下面的效果,说明成功了。

SWR:一个用来简化数据获取的 React Hook

多参数传入

useSWR() 的第一个参数会被原样传递给 fetcher 函数。因此,下面两个写法是等价的:

useSWR('/api/user', url => fetcher(url))
useSWR('/api/user', fetcher)

原理上,**useSWR**** 的第一个参数会作为 SWR key,作为请求和数据缓存的唯一标识,后续再有同样的请求发生时,会直接从缓存里拿到数据,而无需重复请求。**

但我们的请求通常会面临多个参数的传入,这个时候,有 2 种支持方式。

  1. 将字符串传入改用数组传入
  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 库的基本使用方法,其默认配置就能最大程度的提升我们的请求性能了。

其他高级话题,大家可以通过阅读官方文档了解,比如:

  1. 自动重新请求[3]
  2. 条件请求[4]
  3. 数据预请求[5]
  4. 配合 Next.js 中的与渲染方案[6](SSG,SSR)

感谢阅读,Happy Coding!

参考资料

[1]

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

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!