含动态query key的Query无效化操作失效问题求助
React Query 无效化分页查询失效的原因及解决办法
核心原因
React Query 的 invalidateQueries 采用前缀匹配规则,且匹配时严格遵循 queryKey 的元素顺序。你的查询 queryKey 是 [page, QueryClientKeys.QUERY_KEY],而无效化操作传入的是 [QueryClientKeys.QUERY_KEY]——两者元素顺序完全相反,导致无法匹配到目标分页查询。
当你移除 page 后,查询的 queryKey 变为 [QueryClientKeys.QUERY_KEY],和无效化的 key 完全一致,自然能匹配生效。
解决办法
1. 调整 queryKey 顺序(推荐)
把固定的标识放在 queryKey 首位,动态参数放在后面,这样前缀匹配就能覆盖所有分页查询:
export const useQueryExample = ( page: number, project: Lowercase<`${Projects}`> ) => useQuery<ResponseDto>({ queryKey: [QueryClientKeys.QUERY_KEY, page], // 固定标识在前,page在后 queryFn: async () => { const response = await ApiService.getApiExample([project], { page, pageSize: PAGE_SIZE, }); return response.data; }, staleTime: Infinity, cacheTime: Infinity, });
此时原有的无效化代码就能正常工作,会把所有带 QueryClientKeys.QUERY_KEY 前缀的分页查询都标记为失效。
2. 精准匹配特定分页
如果只需要无效化某一页的查询,可在无效化时传入完整的 queryKey(需要获取当前 page 值):
onSuccess: (_data, { project }) => { navigate(`/some/in-app/route`); // 从路由/状态中获取当前page值 const currentPage = 1; // 示例值,实际按需获取 queryClient.invalidateQueries({ queryKey: [currentPage, QueryClientKeys.QUERY_KEY], }); },
3. 用 predicate 函数自定义匹配
不想调整 queryKey 顺序的话,可通过 predicate 函数遍历所有缓存查询,匹配包含指定标识的项:
onSuccess: (_data, { project }) => { navigate(`/some/in-app/route`); queryClient.invalidateQueries({ predicate: (query) => query.queryKey.includes(QueryClientKeys.QUERY_KEY) }); },
内容的提问来源于stack exchange,提问作者mmozedev
相关产品推荐
相关产品推荐

