State
state/query-client-stable
The QueryClient is created once - in useState(() => new QueryClient()) or a module helper - never in a component's render.
seriousstaticfe-data-fetching
Why
const queryClient = new QueryClient() in a component body builds a new, empty cache on every render: every query refetches, loading spinners flash, and a refetch that re-renders the provider can loop. A client at module level is the opposite problem on a server: one cache shared by every request, leaking one user's data to the next.
Fix
In a component, create it once: const [queryClient] = useState(() => new QueryClient({ defaultOptions: { queries: { staleTime: 60_000 } } })). In a framework with server rendering, use a getQueryClient() helper that makes a new client per request on the server and reuses one in the browser. A plain client-only app may keep one module-level client.
Examples
// bad
export function Providers({ children }) {
const queryClient = new QueryClient()
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
}
// good
export function Providers({ children }) {
const [queryClient] = useState(() => new QueryClient())
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
}Sources
Facts
- Id
state/query-client-stable- Severity
- serious
- Check
- static checked in the source by
audit - Applies to
jsx- Only in projects with
tanstack-query- Taught by the skill
fe-data-fetchingData fetching- Since version
- 0.1.0
Read it in the terminal
npx github:dawidolko/frontend-skills explain state/query-client-stable