react-query手把手教程⑧-查询过滤器

419 阅读4分钟

目录

查询过滤器

查询键匹配规则

上一篇文章中通过调用queryClient.refetchQueries方法,并传入['repo']参数,就可以筛选出所有以'repo'打头的查询。

refetchQueries中传入的参数称之为查询过滤器(Query Filters)。查询过滤器对于开发者来说非常重要,因为你可以基于过滤器控制你需要更新数据的颗粒度。

在之前的章节中,笔者曾经提过queryKey的设定非常重要。其实有一方面的原因是在于,规律且合理的queryKey可以方便你去编写查询过滤器

假设现在有下面几组的查询,分散在不同的组件中:

// ①
const repoQuery = useQuery(['repo', org, repo]);
// ②
const repoIssuesQuery = useQuery(['repo', org, repo, 'issues']);
// ③
const openIssuesQuery = useQuery(['repo', org, repo, 'issues', {state: 'open'}]);

如果传入下面的刷新指令,上面的哪几个查询会被刷新?

// 指令①
queryClient.refetchQueries(['repo', org, repo]);

答案是全部都会被刷新,虽然这个非常反直觉,但是实际上确实是一种很便利的方式。它并不会与传入的值进行精确匹配,而是会做部分匹配。可以看到,上面的查询只是前面queryKey路径被匹配上了就代表匹配成功。

请注意:如果初学者没有注意这方面的设计思路,很容易踩坑,导致整体的代码效率下降,后端请求量激增。

好的,理解了上面的内容,接下来看看执行下面的指令,哪几个查询会被刷新?

// 指令②
queryClient.refetchQueries(['repo', org, repo, "issues"]);

没错,相信你一定答对了,是②、③被刷新。

相信你看到这里一定理解了前面章节笔者所说的,querykey的命名最好是以后端资源,从大的概念到小的概念,以此递减。这样在做一些资源的刷新时,可以很方便的控制刷新的颗粒度。如果是胡乱命名,就会导致你后面维护的巨大麻烦。

好了,这里已经知道了react-query会部分匹配传入的查询过滤器,假如不希望做部分匹配,请在第二个参数中传入{exact: true}即可。

比如上面的例子,我们只想②刷新,执行下面的代码即可:

queryClient.refetchQueries(
  ['repo', org, repo, "issues"],
  {exact: true}
);

匹配数据状态及查询的多种状态

在react-query中有以下几种数据状态,现在来总结一下:

  • fresh代表该查询在设定的时间内都是最新的

因为一般的请求数据,默认情况是请求后即是过期状态,如果你认为该数据属于不会被更新的类型,可以设定数据在当前页面不被关闭前永不过期

  • stale表示当前数据已经过期,等待被某些动作触发刷新(前面章节有讲述具体哪些事件)
  • fetching表示当前正在获取数据的查询

同时也有下面三种类型:

  • active:表示某个查询有任何一个组件挂载,react-query就认为它处于活跃状态
  • inactive:表示某个查询没有任何一个组件挂载,react-query会认为该查询是非活跃状态
  • all:以上两种类型

因此还是上面,基于指令②扩展,额外需要重新查询:数据已经过期(slate) 当前处于活跃状态查询,应该执行下面的指令:

queryClient.refetchQueries(
  ['repo', org, repo, "issues"],
  {stale: true, type: "active"}
);

此时查询过滤器已经能满足你在react-query中所有过滤查询的要求了。请一定要注意库中,默认的匹配规则,以及queryKey的命名方式,可以为你后期的开发带来很大的助力。

请注意本章虽然仅使用了queryClient.refetchQueries举例,但是在其他需要进行过滤场景的方法中同样适用。

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 15 天,点击查看活动详情