The Copy Monkey
HomeResourceTrendDemoAboutLink

Made with ❤️ by bhwang

© 2025 The Copy Monkey. All rights reserved.

swr是个好东西

2021-07-22

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

s w r

下面结合我的个人经验,谈谈为什么你应该使用它。

接口请求状态

在请求接口的时候,一般都需要维护请求的状态。比如加载列表的时候,通常都需要区分下 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

请求依赖

当一个请求依赖另一个请求的时候,常规做法是在请求后接另一个请求,这样写起来很复杂。

而 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 的函数。

可以用它来管理全局状态,不管是本地的或者远程的。