目录
- 入门react-query 已于2022-06-04更新
- 深入查询键及查询函数 已于2022-06-08更新
- 并行请求及依赖请求 已于2022-06-19更新
- 查询结果缓存状态与调试工具 已于2022-06-23更新
- 处理错误 已于2022-06-26更新
- 使用QueryClient已于2022-07-27日更新
- 更新查询数据已于2023-02-17日更新
- 查询过滤器已于2023-02-18更新
查询过滤器
查询键匹配规则
上一篇文章中通过调用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 天,点击查看活动详情