使用React状态作为react-query查询键时缓存未过期却重请求的原因
React Query 使用 useState 状态作为查询键时缓存失效的原因
核心问题在于React Query 对查询键的浅比较逻辑,以及不同状态来源的引用稳定性差异:
查询键的比较规则
React Query 判断是否复用缓存的依据是对查询键进行浅比较。对于引用类型(比如对象),浅比较只判断引用地址是否相同,而非对象内部的值。useState 场景的问题
当你使用{ value }作为查询键的一部分时,每次组件因value变化重新渲染时,都会创建一个新的对象实例。即使value从 4444 改回 3336,新的{ value: 3336 }和最初的{ value: 3336 }是两个不同引用的对象。React Query 浅比较查询键时,会认为这是两个不同的查询,因此不会复用之前的缓存,而是重新发起请求。useParams 场景的缓存正常原因
React Router 的useParams()返回的是记忆化的对象:只有当路由参数发生变化时,才会生成新的对象;当路由参数回到之前的值时,返回的是同一个对象引用。因此,查询键中的{ id }引用地址始终一致,React Query 浅比较时会判定为相同的查询键,从而复用已有的缓存。
解决方法
如果要使用 useState 的状态作为查询键,避免用对象包裹基本类型值,直接将基本类型值作为查询键的一部分即可:
const [value, setValue] = useState(3336); const { isLoading: postLoading, data: postData, refetch } = useQuery( ["post", "post", value], // 直接使用value值,而非对象 () => getPost(value + ""), { refetchOnWindowFocus: false, refetchOnMount: false, retry: 0, } );
这样当 value 回到 3336 时,查询键是完全相同的基本类型组合,React Query 会正确复用缓存。
内容的提问来源于stack exchange,提问作者mkp0131
相关产品推荐
相关产品推荐

