在使用了一段时间的 swr 后,它已经加入了“我的最爱”工具库了😂

下面结合我的个人经验,谈谈为什么你应该使用它。
接口请求状态
在请求接口的时候,一般都需要维护请求的状态。比如加载列表的时候,通常都需要区分下 loading、empty、success、error 等状态,然后更新相关的视图,看上去就是下面的代码
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
// more states...
const sendRequest = useCallback(() => {
setLoading(true);
fetchData()
.then(data => {
setLoading(false);
setData(data);
setError(null);
})
.catch(err => {
setLoading(false);
setError(err);
setData(null);
});
}, []);
上面的代码缺陷很多:首先是模板代码多,维护麻烦;第二是容易出错,比如忘记重置相关变量、没考虑竞争等等问题。
而 swr 里面就几行代码:
const fetcher = (url) => fetch(url).then(res => res.json());
// useSwr(apiKey, fetcher, options)
const { data, isValidating, error } = useSwr('/api/list', fetcher);
注意:
- swr 会自动根据 key 来去重,也就是说你在两个不同的组件里请求,只会发一个请求。这对于代码维护就简单太多了。
- 默认开启聚焦重新请求、错误重试等功能,根据你的需要来选择开关。
先缓存后更新
swr 在发起请求的时候,会优先使用缓存的数据,然后当请求返回的时候更新视图。
为什么这个功能很重要呢?还是用上面那个列表接口作为例子,当用户第二次请求接口的时候(比如从某个页面返回),直接就能看到列表里的数据,然后过一会刷新成最新数据,在体验上就感觉很流畅。
如果某个接口更新不是很频繁,那么第二次请求的结果还是原来的数据,用户根本感觉不到有请求的过程,这就很爽😄。
还有个额外的好处,当用户返回之前的页面时,浏览器还能保留滚动位置。

请求依赖
当一个请求依赖另一个请求的时候,常规做法是在请求后接另一个请求,这样写起来很复杂。
而 swr 用了一种很巧妙的方法,当参数抛出异常或者返回 false 值,就不会请求。这种写法省了不少功夫!!
const { data: user } = useSWR('/api/user')
// useSwr(apiKey, fetcher, options)
// apiKey 可以是函数
const { data: projects } = useSWR(() => '/api/projects?uid=' + user.id)
原理是当请求里面的函数抛错的时候,就不会继续请求。
翻页与无穷滚动
这两个场景覆盖了中后台很大的代码(CRUD BOY你懂的),这里官方有例子我不再赘述了。
useSWRImmutable
可以用 useSWRImmutable
来请求不变的数据(比如 select 选项),来避免重复请求。
状态管理
swr 虽然是个用于数据请求的库,但是没有限制 fetcher 的具体实现,他可以是任意返回 promise 的函数。
可以用它来管理全局状态,不管是本地的或者远程的。