QueryClientProvider Error in React Query
When working with React Query (now TanStack Query), one of the most common errors developers encounter is:
Error: No QueryClient set, use QueryClientProvider to set one
This error occurs when you attempt to use React Query hooks like useQuery
without properly setting up the necessary context provider.
Root Cause
React Query requires a QueryClientProvider
to be wrapped around your application component tree. This provider makes the QueryClient
instance available to all components that need to use React Query functionality.
// Incorrect usage - missing QueryClientProvider
import { useQuery } from "@tanstack/react-query";
function MyComponent() {
const { data } = useQuery({ queryKey: ["todos"], queryFn: fetchTodos });
// Error: No QueryClient set
}
Solution: Wrap Your App with QueryClientProvider
The primary solution is to ensure your application is wrapped with the QueryClientProvider
:
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
const queryClient = new QueryClient();
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</React.StrictMode>
);
Alternative: Create a Custom Provider
For cleaner code organization, you can create a custom provider component:
// contexts/ReactQueryProvider.tsx
import React from "react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const queryClient = new QueryClient();
interface Props {
children: React.ReactNode;
}
const ReactQueryProvider: React.FC<Props> = ({ children }) => {
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;
};
export default ReactQueryProvider;
Then use it in your main App component:
import ReactQueryProvider from "./contexts/ReactQueryProvider";
import AppRouter from "./routers/AppRouter";
function App() {
return (
<ReactQueryProvider>
<AppRouter />
</ReactQueryProvider>
);
}
export default App;
Common Pitfalls and Solutions
1. Inconsistent Package Names and Versions
WARNING
Since version 4, React Query was renamed to TanStack Query, which can cause import inconsistencies.
Ensure you're using consistent imports throughout your project:
// For v3 and below:
import { useQuery } from "react-query";
// For v4 and above:
import { useQuery } from "@tanstack/react-query";
Check your package.json
to ensure you don't have both packages installed:
// Remove any duplicates
{
"dependencies": {
"@tanstack/react-query": "^5.0.0",
// Remove if present: "react-query": "^3.0.0"
}
}
2. Provider Order Issues
Ensure QueryClientProvider
wraps all components that use React Query hooks:
// Incorrect: ModalContextProvider wraps QueryClientProvider
<ModalContextProvider>
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
</ModalContextProvider>
// Correct: QueryClientProvider wraps other providers
<QueryClientProvider client={queryClient}>
<ModalContextProvider>
{children}
</ModalContextProvider>
</QueryClientProvider>
3. Using Hooks Outside the Provider
You cannot use useQuery
in the same component where you define the QueryClientProvider
:
// Incorrect usage
function App() {
const queryClient = new QueryClient();
const { data } = useQuery({ queryKey: ["user"], queryFn: fetchUser }); // Error!
return (
<QueryClientProvider client={queryClient}>
{/* ... */}
</QueryClientProvider>
);
}
// Correct: Separate concerns
function AppContent() {
const { data } = useQuery({ queryKey: ["user"], queryFn: fetchUser });
// ...
}
function App() {
const queryClient = new QueryClient();
return (
<QueryClientProvider client={queryClient}>
<AppContent />
</QueryClientProvider>
);
}
4. DevTools Import Issues
Different versions require different import paths for devtools:
// For v3:
import { ReactQueryDevtools } from 'react-query/devtools';
// For v4+:
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
5. Context Sharing in Microfrontends
For microfrontend architectures or complex applications, enable context sharing:
<QueryClientProvider client={queryClient} contextSharing={true}>
{children}
</QueryClientProvider>
This ensures multiple instances of React Query across different bundles use the same context.
6. Module System Inconsistencies
Use consistent import styles throughout your project:
// Avoid mixing require and import
const { useQuery } = require("@tanstack/react-query"); // Inconsistent
// Use ES6 imports consistently
import { useQuery } from "@tanstack/react-query";
Testing Considerations
When testing components that use React Query, wrap them in a QueryClientProvider
:
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { render } from '@testing-library/react';
const queryClient = new QueryClient();
describe('Example component', () => {
it('renders correctly', () => {
render(
<QueryClientProvider client={queryClient}>
<ExampleComponent />
</QueryClientProvider>
);
});
});
Conclusion
The "No QueryClient set" error is easily resolved by ensuring:
- Your app is wrapped with
QueryClientProvider
- You're using consistent package imports throughout your project
- The provider hierarchy is correct (QueryClientProvider should wrap other providers)
- You're not mixing different versions of React Query/TanStack Query
By following these practices, you'll avoid this common error and ensure proper functioning of React Query in your application.