使用react-query时如何从兄弟组件触发对应查询重新请求
问题原因与解决方案
核心错误点
你代码无法生效的根源是在ComponentB内部单独实例化了新的QueryClient,和ComponentA使用的不是同一个实例,二者状态完全隔离,自然无法触发ComponentA对应的查询重取。
React Query基于Context实现的全局状态共享有两个必要前提:
- 整个应用仅初始化一个全局唯一的
QueryClient实例 - 所有用到React Query能力的组件,都在
QueryClientProvider包裹的组件树范围内,且Provider绑定的是上面的全局实例
你当前既没有在上层挂载Provider,还在ComponentB内单独新建了实例,所以调用refetchQueries完全找不到ComponentA中注册的查询。
修改步骤
1. 上层挂载QueryClientProvider
在Page组件(或应用入口文件)中初始化全局QueryClient,并用Provider包裹所有子组件,修改后的Page.js代码如下:
import { QueryClient, QueryClientProvider } from "react-query"; import ComponentA from "./componentA"; import ComponentB from "./componentB"; // 全局唯一实例,不要写在组件内部避免渲染时重复初始化 const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: Infinity, }, }, }); function Page(){ return( <QueryClientProvider client={queryClient}> <div> <ComponentA/> <ComponentB/> </div> </QueryClientProvider> ) }
2. 修正ComponentB的实例获取逻辑
ComponentB中不要自行新建QueryClient,改用useQueryClient钩子获取全局实例,修改后的代码如下:
import { useQueryClient } from "react-query"; function ComponentB(){ // 从上层Provider获取全局唯一实例 const queryClient = useQueryClient() const refreshQueryFromComponentA = async () => { await queryClient.refetchQueries(["queryA"], { active: true }) } return( <div> <button onClick={refreshQueryFromComponentA}>刷新ComponentA数据</button> </div> ) }
ComponentA的代码无需修改,调整后即可在ComponentB中触发ComponentA的查询重取。
补充说明
- 你传入的
{ active: true }参数表示仅重取当前已挂载组件绑定的活跃查询,若需要在ComponentA未挂载时也提前重取缓存,可以删除该参数,或替换为{ type: 'all' } - 如果不需要立即重取,仅希望标记缓存失效、下次组件挂载时自动拉取最新数据,更符合React Query设计逻辑的写法是调用
queryClient.invalidateQueries(["queryA"])
内容的提问来源于stack exchange,提问作者Re-Angelo
相关产品推荐
相关产品推荐

