React 优化:在 ahooks - useRequest 中利用 swr 优化网络请求
携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情
这是我关于 ahooks - useRequest 系列文章的第三篇,前两篇请查看:
通过前两篇文章我们已经基本了解了关于服务端状态管理的概念,也通过 useRequest 体验了一系列有趣的功能,认识到了其强大之处。
本文我们将继续介绍 useRequest 的进阶用法,主要是:swr 。
什么是 swr
什么是 swr?我们这里引用一段 SWR 官方的介绍:
The name “SWR” is derived from
stale-while-revalidate
, a HTTP cache invalidation strategy popularized by HTTP RFC 5861. SWR is a strategy to first return the data from cache (stale), then send the fetch request (revalidate), and finally come with the up-to-date data.“SWR”这个名称来源于 stale-while-revalidate,这是一种由 HTTP RFC 5861 推广的 HTTP 缓存失效策略。SWR 是一种首先从缓存中返回数据(stale),然后发送 fetch 请求(revalidate)的策略,最终使用新的数据。
简而言之,当我们的某个请求存在缓存时,我们优先使用缓存数据展示在页面上,同时在背后发出请求,请求成功后再使用最新获取的数据来更新UI。
这种方式可以提升用户体验,使得 UI 界面在用户眼中总是有内容有数据的。在大部分场景中,当频繁的页面打开、回退时,用户并不在意其中的数据实时性。
很多数据甚至本就不具备实时性,这样的数据如果可以缓存,无疑可以减少 loading 时长。
使用 swr
在 useRequest 中也是具备了 swr 的能力的,使用起来也是十分简单,最简单的方式就是配置一个 options.cacheKey
,是的,你只需要配置这个 cacheKey 就可以让你的请求具备 swr 的能力
1 | // 请求知乎专栏的接口 |
现在我们的接口已经自动的具备了缓存,每次发起请求时,会优先从缓存中获取数据用于显示,当接口返回后,才会使用新的数据更新 UI 与缓存。
Gif效果对比:
未使用 swr,每次都要等待重新请求后才能填充数据:
使用 swr,先使用缓存数据填充,等到新数据请求完成后再更新:
可以清楚的看出,未使用时,每次请求都是先 loading 然后显示内容。
而使用 swr 后,第一次也是先loading 然后显示内容,再之后的每次都是先使用缓存,再更新UI。
配置缓存时间与新鲜时间
options.cacheTime
可以配置缓存时间,超时后会移除缓存,单位为毫秒,默认值是 300000 (5分钟)。该参数设置主要针对的是,两次请求之间缓存有效期,例如我们设置 options.cacheTime
为 1000,但是我们两次触发请求的间隔为 2 秒,那么表现出来的效果等同于没有配置缓存。
options.staleTime
可以配置数据保鲜时间,单位为毫秒,默认值 0 。在保鲜期内的我们认为数据是可靠的,即使请求被重新触发,也不会在背后发起真实的请求,直到过了数据保鲜期才会真正的发送请求。
1 | const { data, loading } = useRequest(getZhuhuColum, { |
这里我录制了一个Gif ,可以很好的展示这一点:
我们可以看到在第一条数据发送后,尽管我们多次重新挂载组件触发请求,但是都没有真正发起请求,使用的都是缓存中的数据,直达过了数据保鲜期后,才发出了第二条请求。
数据共享
我们使用 swr 时还有一点需要注意,那就是数据共享,同一个 cacheKey 的数据时全局共享的,这使得:
请求 Promis 共享,多个具有相同 cacheKey 的请求,同时只会有一个发起请求,后发起的将会共用该Promise
从这张图片也能看出,两个组件同时发起了相同的请求,实际只发出了一次真正的请求。当这些请求中的某一个重新发起更新了数据后,其他的也会一起变更,就如同我们使用 redux 进行全局状态管理的效果一样。
注意这里无论是 mutate 、run、还是 refresh ,只要任意某个请求触发了数据状态的变化,那么全局内数据状态都会变化。
基于上面两点,我们一定要注意 cacheKey 的设置,一般的我们以 接口名称+参数
的拼接字符串作为 key,如果你用过 react-query,就会发现这和 RQ 中的 QueryKey 是一个概念(但是这里类型只能是字符串,RQ支持的类型更多)。
删除缓存
既然由缓存,那自然也就有缓存的移除,ahooks 提供了一个函数,专门用于移除指定 cacheKey 的缓存数据
1 | import { useRequest, clearCache } from 'ahooks'; |
什么情况我们需要使用这个函数?
举个例子,我们访问了某个列表页面,请求了一次列表(使用了cacheKey缓存),然后我们在其中的一项的详情页面,删除了这一项。
这时如果此时还处于我们设置的数据保鲜期options.staleTime
内,再回到列表页面时,是不会触发请求的,会直接使用就的缓存(此时已经减少了一项),这样显然是很差的体验。
这时我们就可以在删除事件中调用删除缓存函数,这样再回到列表页面时,由于没有缓存数据,会再次发起请求,使用新的数据!
clearCache
函数还可以同时删除多个,只需要传入 cacheKey 的数组即可
总结
通过三篇文章的介绍,想必大家对服务端状态管理这个概念已经有了更为深刻的认识了吧,如果你觉得本文有帮助到你,欢迎点赞、收藏,更多有关 React 文章,请关注我的专栏。