React 数据请求最佳实践

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 1 天,点击查看活动详情

我们在开发 Web 应用时,调用后端 API 的最常见方式无外乎 fetch 和 Axios,它们都可以非常方便的和后端 API 进行数据交互。特别是 Axios,由于它的功能更加强大,而且易于上手,几乎已经是最受欢迎的第三方 HTTP 请求库了。
但是它们的功能比较单一,只是发送或者获取数据而已。如果我们需要缓存请求的数据或者处理数据分页,都需要自己来编写逻辑。
在本文中,我将介绍一个同样是用于 HTTP 请求的库:SWR。它可以帮助我们将数据请求这件事做得更好。
首先我要说明一点,SWR 是一个 React Hooks 库,所以它只支持 React 一个 UI 框架。如果你采用的不是 React,那么可以尝试 query 这个库,它支持 React、Vue、Solid 和 Svelte,而且功能和 SWR 不相上下。

什么是 SWR?

SWR 代表的是一个缩写,全拼是 stale-while-revalidate,它是由 HTTP RFC 5861 所推广的一种 HTTP 缓存失效策略。
它规定了,应该由 3 个步骤来执行数据获取:

  1. 首先返回缓存数据(过期数据)
  2. 发送 HTTP 请求(重新验证)
  3. 最后返回最新数据

SWR 这个库由知名的网站托管平台 Vercel 创建并开源,非常轻量和快速,在基本的数据获取功能之上添加了一系列额外的功能,比如缓存、分页、自动重新验证等。

SWR 的基本用法

在这里我将演示 SWR 最基本的用法,目的是让大家对它有一个基本的认识。更多使用教程可以查看官方文档。

安装

首先需要安装 SWR。

npm i swr

编写 fetcher 函数

SWR 在设计上对 HTTP 请求库进行了解耦,也就是说我们可以和任何 HTTP 请求库一起使用。
我们这里演示和 Axios 一起使用。
首先安装 Axios。

npm i axios

接下来编写 fetcher 函数。

import axios from 'axios'

const fetcher = config => axios(config).then(res => res.data)

请求数据

有了 fetcher 之后,我们就可以使用 useSWR 来请求数据了。
useSWR 是一个 React Hooks,它的第一个参数是请求的 URL,第二个参数是 fetcher。返回的是一个对象,对象中包含两个 key,一个是 data,一个是 error。data 为 undefined 时,表示正在请求,data 有值,表示数据获已返回。error 不为 undefined,表示数据获取发生了错误。
我们可以通过 data 和 error 的值来展示不同的 UI。
模拟数据的 API 可以使用 jsonplaceholder 提供的免费 API。
下面是完整的代码示例。

import useSWR from "swr";
import axios from 'axios'
import "./App.css";

const fetcher = config => axios(config).then(res => res.data)

function App() {
  const { data, error } = useSWR(
    "https://jsonplaceholder.typicode.com/todos/1",
    fetcher
  );

  if (error) return <div>failed to load</div>;
  
  if (!data) return <div>loading...</div>;

  return (
    <div className="App">
      <h2>{data.title}</h2>
      <p>UserId: {data.userId}</p>
      <p>Id: {data.id}</p>
      {data.completed? <p>Completed</p> : <p>Not Completed</p>}
    </div>
  );
}

export default App;

SWR 核心功能

缓存与实时数据

在 SWR 获取到数据后,会将数据进行缓存。当需要向用户展示数据时,优先展示缓存的数据。同时会去请求 API 获取最新数据,当获取到最新数据后,更新 UI,并且将最新数据进行缓存。SWR 会使用轮询的方式不断获取最新的数据,始终保持 UI 上面展示的数据是最新的。

自动重新验证

SWR 始终确保用户看到的是最新数据。所以当我们存在多个选项卡或者浏览器窗口时,它们之间的数据也是最新且同步的。SWR 的轮询请求数据可以同步所有的选项卡和窗口。
当用户断开互联网,重新联网后,SWR 会继续工作。
你可以想象,当用户的电脑休眠后重新激活,可以立即获取最新的数据。

分页

分页是 SWR 一个非常有用的特性。
常见的分页方式有两种,一种是基于索引(index),一种是基于游标(cursor)。
基于索引的分页方案通常都需要自己去维护分页参数。使用 SWR 可以非常简单的处理这个问题,不需要我们再编写任何逻辑。
基于游标的分页方案在逻辑上会更加复杂,因为它会依赖上一页的数据。针对这种情况,SWR 还提供了另外一个非常简单的 useSWRInfinite Hooks。
使用 useSWRInfinite 可以处理基于游标的分页,同时还可以处理无限加载的场景,我们同样不需要去额外处理数据。这一切 SWR 都帮我们处理好了。

其他

除了上面提到的几点最重要的核心功能外,SWR 还有一些其他功能:

  • 预请求。
  • 智能错误重试。
  • 支持 RESTful API 和 GraphQL API。
  • 支持 SSR/ISR/SSG。
  • 支持 TypeScript。
  • 支持 React Native。

最后,SWR 的主要功能是获取数据,而不是发送数据。如果你需要发送数据,可以直接使用 fetch 或者 Axios,不过也可以使用 SWR 的 mutate 功能来实现乐观 UI。

总结

通过阅读文本,我们了解了什么是 SWR,SWR 的功能特性、以及 SWR 和 React 的结合使用。它非常轻量,并且与后端无关。它的缓存、分页和自动重新获取等功能都可以很好的提高用户体验度。
如果你也是 React 的使用者,不妨把 SWR 加入到你的应用中,相信它能够让你的应用变得更好。
感谢你的阅读,如果本文对你有所帮助,不妨点个赞吧。

猜你喜欢

转载自juejin.im/post/7126050290914525220