QueryClientProvider
The QueryClientProvider component provides the QueryClient instance to your React application. It must wrap any components that use TanStack Query hooks.
Import
import { QueryClientProvider } from '@tanstack/react-query'
Signature
function QueryClientProvider({
client,
children,
}: QueryClientProviderProps): React.JSX.Element
Props
The QueryClient instance to provide to the application. Create this using new QueryClient().
The React components that will have access to the QueryClient.
Behavior
The QueryClientProvider component:
- Creates a React Context to provide the QueryClient
- Calls
client.mount() when the component mounts
- Calls
client.unmount() when the component unmounts
- Makes the QueryClient available to all child components via the
useQueryClient hook
Examples
Basic Setup
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
// Create a client
const queryClient = new QueryClient()
function App() {
return (
<QueryClientProvider client={queryClient}>
<YourApp />
</QueryClientProvider>
)
}
With Custom Configuration
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60 * 5, // 5 minutes
gcTime: 1000 * 60 * 10, // 10 minutes
refetchOnWindowFocus: false,
retry: 1,
},
mutations: {
retry: 1,
},
},
})
function App() {
return (
<QueryClientProvider client={queryClient}>
<YourApp />
</QueryClientProvider>
)
}
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
const queryClient = new QueryClient()
function App() {
return (
<QueryClientProvider client={queryClient}>
<YourApp />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
)
}
Multiple Clients (Advanced)
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
const publicClient = new QueryClient()
const adminClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 0, // Always refetch for admin
},
},
})
function App() {
return (
<QueryClientProvider client={publicClient}>
<PublicApp />
<QueryClientProvider client={adminClient}>
<AdminPanel />
</QueryClientProvider>
</QueryClientProvider>
)
}
With Persistence (Server-Side Rendering)
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { useState } from 'react'
function App({ pageProps }: AppProps) {
// Create a new client for each request to avoid sharing data between users
const [queryClient] = useState(
() =>
new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 1000,
},
},
})
)
return (
<QueryClientProvider client={queryClient}>
<Component {...pageProps} />
</QueryClientProvider>
)
}
Accessing the Client in Components
import { useQueryClient } from '@tanstack/react-query'
function MyComponent() {
// Access the QueryClient from context
const queryClient = useQueryClient()
const handleInvalidate = () => {
queryClient.invalidateQueries({ queryKey: ['todos'] })
}
return <button onClick={handleInvalidate}>Refresh</button>
}
useQueryClient
The useQueryClient hook allows you to access the QueryClient instance from any component within the provider:
import { useQueryClient } from '@tanstack/react-query'
function MyComponent() {
const queryClient = useQueryClient()
// Use queryClient methods:
// - queryClient.invalidateQueries(...)
// - queryClient.setQueryData(...)
// - queryClient.getQueryData(...)
// - queryClient.refetchQueries(...)
// etc.
}
Implementation Details
The implementation creates a React Context and manages the QueryClient lifecycle:
export const QueryClientContext = React.createContext<QueryClient | undefined>(
undefined,
)
export const useQueryClient = (queryClient?: QueryClient) => {
const client = React.useContext(QueryClientContext)
if (queryClient) {
return queryClient
}
if (!client) {
throw new Error('No QueryClient set, use QueryClientProvider to set one')
}
return client
}
export const QueryClientProvider = ({
client,
children,
}: QueryClientProviderProps): React.JSX.Element => {
React.useEffect(() => {
client.mount()
return () => {
client.unmount()
}
}, [client])
return (
<QueryClientContext.Provider value={client}>
{children}
</QueryClientContext.Provider>
)
}
Common Patterns
Single Client Instance
// queryClient.ts
import { QueryClient } from '@tanstack/react-query'
export const queryClient = new QueryClient()
// App.tsx
import { QueryClientProvider } from '@tanstack/react-query'
import { queryClient } from './queryClient'
function App() {
return (
<QueryClientProvider client={queryClient}>
<YourApp />
</QueryClientProvider>
)
}
Per-Request Client (SSR)
// _app.tsx (Next.js)
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { useState } from 'react'
function MyApp({ Component, pageProps }) {
const [queryClient] = useState(() => new QueryClient())
return (
<QueryClientProvider client={queryClient}>
<Component {...pageProps} />
</QueryClientProvider>
)
}
With Error Handling
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
const queryClient = new QueryClient({
defaultOptions: {
queries: {
throwOnError: true, // Throw errors to Error Boundaries
},
},
})
function App() {
return (
<QueryClientProvider client={queryClient}>
<ErrorBoundary fallback={<ErrorFallback />}>
<YourApp />
</ErrorBoundary>
</QueryClientProvider>
)
}
Best Practices
- Create client outside component: Create the QueryClient instance outside your component or use
useState to ensure it’s only created once
- Don’t create new clients on every render: This will cause all queries to reset
- Place high in component tree: Wrap your entire app or the highest level component that needs TanStack Query
- Use single client for most apps: Most applications only need one QueryClient instance
- SSR considerations: Create a new client per request in SSR environments to avoid sharing data between users
- DevTools in development: Include ReactQueryDevtools only in development builds
Type Definition
export type QueryClientProviderProps = {
client: QueryClient
children?: React.ReactNode
}
Source
Implementation: QueryClientProvider.tsx:29