Setup
import { QueryClient } from '@tanstack/react-query'
export const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 60_000,
gcTime: 10 * 60_000,
retry: 2,
refetchOnWindowFocus: true,
},
},
})
Core Patterns
Set freshness close to the data source
import { queryOptions } from '@tanstack/react-query'
export const settingsOptions = queryOptions({
queryKey: ['settings'],
queryFn: async () => ({ theme: 'system' }),
staleTime: 5 * 60_000,
})
Disable retries in tests
import { QueryClient } from '@tanstack/react-query'
export function createTestQueryClient() {
return new QueryClient({
defaultOptions: { queries: { retry: false } },
})
}
Use networkMode deliberately
import { queryOptions } from '@tanstack/react-query'
export const metricsOptions = queryOptions({
queryKey: ['metrics'],
queryFn: async () => ({ count: 1 }),
networkMode: 'online',
})
Common Mistakes
HIGH Confusing gcTime with freshness
Wrong:
import { useQuery } from '@tanstack/react-query'
export function useProfile() {
return useQuery({
queryKey: ['profile'],
queryFn: async () => ({ name: 'Tanner' }),
gcTime: 60_000,
})
}
Correct:
import { useQuery } from '@tanstack/react-query'
export function useProfile() {
return useQuery({
queryKey: ['profile'],
queryFn: async () => ({ name: 'Tanner' }),
staleTime: 60_000,
})
}
gcTime controls unused cache retention; staleTime controls whether cached data is considered fresh.
Source: TanStack/query:docs/framework/react/guides/important-defaults.md
HIGH static staleTime blocks invalidation expectations
Wrong:
import { useQuery } from '@tanstack/react-query'
export function useTodos() {
return useQuery({
queryKey: ['todos'],
queryFn: async () => [{ id: 1 }],
staleTime: 'static',
})
}
Correct:
import { useQuery } from '@tanstack/react-query'
export function useTodos() {
return useQuery({
queryKey: ['todos'],
queryFn: async () => [{ id: 1 }],
staleTime: 60_000,
})
}
staleTime: 'static' opts out of refetching even when the query is invalidated.
Source: TanStack/query:docs/framework/react/guides/important-defaults.md
HIGH Tests hang on retries
Wrong:
import { QueryClient } from '@tanstack/react-query'
export const queryClient = new QueryClient()
Correct:
import { QueryClient } from '@tanstack/react-query'
export const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false } },
})
Default retries add delay and can make failing tests wait before surfacing errors.
Source: TanStack/query:docs/framework/react/guides/testing.md
See also: compositions/persist-offline-and-restore-caches for persistence rules that depend on gcTime and networkMode.