查看原文
其他

【第1795期】SWR:最具潜力的 React Hooks 数据请求库

chenbin92 前端早读课 2019-12-04

前言

使用木剑之前先用重剑纵横江湖。今日早读文章由阿里@chenbin92授权分享。

正文从这开始~~

说明:本文内容主要来源于 SWR 的 官方文档 以及 GitHub zeit/swr 仓库,本篇主要为功能简介篇。

简介

React Hooks library for remote data fetching

一个用于请求远程数据的 React Hooks 库,官网的快速开始示例如下:

  1. import useSWR from'swr'


  2. functionProfile() {

  3. const{ data, error } = useSWR('/api/user', fetch)


  4. if(error) return<div>failed to load</div>

  5. if(!data) return<div>loading...</div>

  6. return<div>hello {data.name}!</div>

  7. }

上述示例是一个最基础的前端基础请求例子, useSWR 接受一个 key 和一个异步请求函数 fetch 作为参数。key 是数据的唯一标识符,通常是 API URL,并且 fetch 接受 key 作为其参数,完成具体的数据请求行为并异步返回数据。

useSWR 返回 2 个值:data 和 error , 分别对应请求返回的数据结果和错误,当 data 为空时,可以指定渲染对应的 UI;当请求(获取)尚未完成时,数据将是 undefined 的;当得到响应时它会根据获取的结果设置 data 和 error 然后重新渲染组件。其中第二个参数 fetch 部分可以是任何异步函数,因此可以使用你喜欢的任何数据获取库来处理这这部分。

功能

SWR 相比常见的数据请求库提供了很多很酷且很有脑洞的特性,比如导航切换时使用缓存数据进行优先渲染然后在进行对比更新,数据在 focus 时更新,轮询检查更新,分页按需更新等等。

  • Transport and protocol agnostic data fetching

  • Fast page navigation

  • Revalidation on focus

  • Interval polling

  • Local mutation

  • Pagination

  • TypeScript ready

  • Suspense mode

  • Minimal API

Focus Revalidation

当重新聚焦页面或在不同的标签页之间切换时,SWR 会自动重新获取数据,这对于立即同步到最新状态很有用。常见的场景如电脑进入睡眠状态的情况下,重新刷新数据是很有帮助的。

如下演示:使用焦点自动在页面之间同步登录状态。

Fast Navigation

当浏览页面或系统中的某个部分时,也或者当点击返回按钮时,SWR 将会加载缓存的数据,同时为了达到最终数据的一致性,一旦从缓存加载数据,SWR 会自动重新获取原始的数据。

如下演示:SWR 通过使用缓存数据使得页面显示得更快,然后用最新的数据更新缓存。

Refetch on Interval

在许多情况下,由于多个设备、多个用户、多个选项卡,数据会发生更改。随着时间的推移,我们如何更新屏幕上的数据?SWR 也提供了自动重新提取数据的选项,且只有与 hook 相关的组件在屏幕上时才会进行重新更新。

如下演示:当进行更改是,两个会话最终呈现相同的数据。

Local mutation

在许多情况下,对数据应用局部突变是一种让更改感觉更快的好方法—无需等待远程数据源。局部突变是一种完全可选的方法,用于设置临时的局部状态,该状态将在下次重新验证时自动更新。

SWR 提供了一个 mutate 方法来直接修改请求返回的数据,此时请求中的 key 就派上用场了。官方给的例子是用于乐观更新,提交表单时提前修改前端展现的数据,然后发请求进行 revalidate 更新。

长按识别查看演示视频

Scroll Position Recovery and Pagination

SWR 内置支持数据以 块(chunks) 的形式返回数据的 APIs ,以及用于"加载更多"的相应 UI。此外,当导航回到“加载更多”的列表时,包括滚动位置在内的所有内容都将自动恢复。

如下:ZEIT 仪表板上的无限滚动用户界面,SWR 将恢复你的滚动位置。

长按识别查看演示视频

Custom Data Fetching

SWR 默认用原生的 fetch 做请求,并假设使用 REST 风格的 API 进行调用,但是你也可以指定其他的任何异步请求库作为第二个参数,比如下面的例子是 graphql 示例:

  1. import{ request } from'graphql-request'

  2. import useSWR from'swr'


  3. const API = 'https://api.graph.cool/simple/v1/movies'


  4. functionProfile() {

  5. const{ data, error } = useSWR(

  6. `{

  7. Movie(title: "Inception") {

  8. releaseDate

  9. actors {

  10. name

  11. }

  12. }

  13. }`,

  14. query => request(API, query)

  15. )


  16. if(error) return<div>failed to load</div>

  17. if(!data) return<div>loading...</div>

  18. return<div>Movie: {data.title}!</div>

  19. }

Dependent Fetching

SWR 允许获取依赖于其他数据的数据,它可以确保最大程度的并行性(avoiding waterfalls)。

  1. import useSWR from'swr'


  2. functionMyProjects() {

  3. const{ data: user } = useSWR('/api/user')

  4. const{ data: projects } = useSWR(

  5. () => '/api/projects?uid='+ user.id

  6. )

  7. // When passing a function, SWR will use the

  8. // return value as `key`. If the function throws,

  9. // SWR will know that some dependencies are not

  10. // ready. In this case it is `user`.


  11. if(!projects) return'loading...'

  12. return'You have '+ projects.length + ' projects'

  13. }

Suspense

还可以将 SWR Hooks 与 React Suspense 一起使用,只需 SWR 的配置中启用 suspense: true ,一切都会顺利进行。

  1. import{ Suspense} from'react'

  2. import useSWR from'swr'


  3. functionProfile() {

  4. const{ data } = useSWR(

  5. '/api/user',

  6. fetch,

  7. { suspense: true}

  8. )

  9. return<div>hello, {data.name}</div>

  10. }


  11. functionApp() {

  12. return(

  13. <Suspense fallback={<div>loading...</div>}>

  14. <Profile/>

  15. </Suspense>

  16. )

  17. }

总结

目前来看 SWR 主要是基于 stale-while-revalidate 概念,实现的一个 React Hooks 版本的数据请求库,可以从上面分析的功能发现其核心是专注在 异步数据请求 这个最基本的诉求上,同时带入了很多新的脑洞以及很多新思路,相比现有的请求库未来可能有更多的可能性,是具有较大潜力的请求类工具库。

关于本文 作者:@chenbin92 原文:https://zhuanlan.zhihu.com/p/89570321

为你推荐


【第1793期】理解 React 的下一步:Concurrent Mode 与 Suspense


【第1788期】React Hooks: 没有魔法,只是数组

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存