调用含react-query的自定义npm包 已配Provider仍报无QueryClient错误
问题根因
你遇到的报错本质是项目中存在两份独立的react-query副本:Demo项目入口配置的QueryClientProvider属于Demo侧安装的react-query实例,而Core包内调用的useQuery、useQueryClient绑定的是Core包自身依赖的react-query实例,两个实例上下文完全隔离,因此无法读取到上层配置的QueryClient。
最优解决方案(Core包侧配置)
将react-query以及react、react-dom调整为Core包的对等依赖(peerDependencies),强制Core包使用上层应用安装的react-query副本,从根源避免多实例问题。
操作步骤:
- 调整Core包的
package.json配置:
- 把
dependencies中的react、react-dom、react-query移除 - 在
peerDependencies中添加对应依赖,声明兼容版本范围即可,示例:
{ "peerDependencies": { "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0", "react-query": "^3.0.0" }, "devDependencies": { "react": "^18.0.0", "react-dom": "^18.0.0", "react-query": "^3.39.3" } }
- 清理Core包本地的
node_modules、package-lock.json后重新安装依赖,再走原有构建发布流程上传到私有源。 - Demo侧清理
node_modules、package-lock.json后重新安装Core包,即可正常调用对应hook。
备选解决方案(手动传递QueryClient)
如果不方便调整Core包的依赖配置,可以修改Core包的自定义hook,支持上层传入QueryClient:
修改Core包hook代码:
export function useHookWithUseQuery(customQueryClient) { // 优先使用传入的client, fallback到上下文读取 const queryClient = customQueryClient || useQueryClient(); const { data } = useQuery( "QUERY_KEY", getDataFn, // 传入自定义client时指定给useQuery customQueryClient ? { client: customQueryClient } : undefined ); const invalidateData = () => { queryClient.invalidateQueries("QUERY_KEY"); }; return { data, invalidateData }; }
Demo侧调用方式:
import { useQueryClient } from 'react-query' import { useHookWithUseQuery } from "core/dist/hooks"; function App() { const queryClient = useQueryClient() const { data } = useHookWithUseQuery(queryClient); const { someFetchedText } = data; return ( <div>{ someFetchedText }</div> ); }
临时兼容方案(Demo侧强制统一依赖版本)
如果不需要改动Core包,也可以在Demo侧的package.json中添加依赖强制解析规则,确保项目中所有react-query都使用同一个版本:
- 如果你使用npm/yarn,添加
resolutions字段:
{ "resolutions": { "react-query": "^3.39.3" } }
- 如果你使用pnpm,添加
pnpm.overrides字段:
{ "pnpm": { "overrides": { "react-query": "^3.39.3" } } }
配置完成后清理锁文件和node_modules,重新安装依赖即可生效。
内容的提问来源于stack exchange,提问作者davsto
相关产品推荐
相关产品推荐

