如何在Storybook中配置tanstack/react-query的QueryClientProvider
解决Storybook中React Query的
No QueryClient set错误 问题背景
在Storybook中运行使用React Query的组件时,出现错误:No QueryClient set, use QueryClientProvider to set one。虽然在Next.js的_app.tsx中已正确配置QueryClientProvider,且尝试了两种在Storybook中包裹故事的方式(元数据装饰器、单个故事直接包裹),但均无效。
解决方案
1. 全局配置Storybook装饰器(推荐)
在Storybook的全局预览配置文件(.storybook/preview.tsx或.storybook/preview.js)中添加全局装饰器,确保所有故事都被QueryClientProvider包裹:
// .storybook/preview.tsx import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import type { Preview } from '@storybook/react'; // 创建QueryClient实例,可按需配置默认选项 const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false, // 可选:禁用默认重试,避免Storybook中触发不必要的请求 }, }, }); const preview: Preview = { decorators: [ (Story) => ( <QueryClientProvider client={queryClient}> <Story /> </QueryClientProvider> ), ], // 其他Storybook配置(如parameters等) }; export default preview;
配置完成后重启Storybook服务,确保配置生效。
2. 检查组件内useQuery的调用时机
确保所有useQuery/useInfiniteQuery等React Query钩子都在组件的渲染函数内部调用,而非组件顶层(否则会在Storybook的Provider包裹前执行,导致错误)。
错误示例:
// ❌ 错误:useQuery在组件顶层执行 const { data } = useQuery({ queryKey: ['auth'], queryFn: fetchAuthData }); const AuthenticationPage = () => { return <div>{data?.status}</div>; };
正确示例:
// ✅ 正确:useQuery在组件渲染函数内调用 const AuthenticationPage = () => { const { data } = useQuery({ queryKey: ['auth'], queryFn: fetchAuthData }); return <div>{data?.status}</div>; };
3. 兼容React Query DevTools(可选)
如果项目中使用了ReactQueryDevTools,需将其也包裹在QueryClientProvider内,避免额外错误:
// .storybook/preview.tsx import { QueryClient, QueryClientProvider, ReactQueryDevTools } from '@tanstack/react-query'; // ... 其他配置 const preview: Preview = { decorators: [ (Story) => ( <QueryClientProvider client={queryClient}> <Story /> <ReactQueryDevTools initialIsOpen={false} /> </QueryClientProvider> ), ], };
验证步骤
- 重启Storybook服务,确保全局配置生效
- 移除单个故事中手动添加的
QueryClientProvider包裹(全局配置已覆盖) - 检查组件是否存在异步导入/懒加载场景,确保这类组件也被全局Provider覆盖
内容的提问来源于stack exchange,提问作者webber
相关产品推荐
相关产品推荐

