QueryClient в TanStack Query является центральной точкой
управления всеми аспектами работы с серверным состоянием: кеширование,
повторные запросы, фоновые обновления, синхронизация мутаций и
взаимодействие с жизненным циклом приложения. Его кастомизация
определяет поведение всей системы запросов и часто становится ключевым
инструментом для настройки производительности и предсказуемости
данных.
Экземпляр QueryClient создаётся один раз на приложение и
передаётся через QueryClientProvider. Однако его поведение
почти полностью определяется набором опций, которые можно задать при
инициализации.
import { QueryClient } from '@tanstack/react-query'
const queryClient = new QueryClient({
defaultOptions: {},
})
defaultOptions — это первый уровень настройки, через
который задаётся поведение всех queries и
mutations. Эти параметры применяются ко всем хук-вызовам,
если они не переопределены локально.
const queryClient = new QueryClient({
defaultOptions: {
queries: {},
mutations: {},
},
})
Ключевые настройки, влияющие на поведение запросов:
Определяет время, в течение которого данные считаются актуальными.
staleTime: 1000 * 60 * 5 // 5 минут
Высокое значение снижает количество повторных запросов и повышает эффективность кеша.
Определяет время жизни неиспользуемых данных в кеше.
cacheTime: 1000 * 60 * 30
Если запрос не используется компонентами, он удаляется после истечения этого времени.
Контролирует автоматическое обновление данных при возврате фокуса на вкладку.
refetchOnWindowFocus: true
Полезно для данных, которые быстро устаревают (дашборды, финансы), но может создавать лишнюю нагрузку.
Запускает повторный запрос при восстановлении сети.
refetchOnReconnect: true
Количество попыток повторного запроса при ошибке.
retry: 2
Можно также задать функцию для гибкой логики:
retry: (failureCount, error) => {
return error.status !== 404 && failureCount < 3
}
Интервальный polling:
refetchInterval: 1000 * 10
Используется для realtime-подобных сценариев без WebSocket.
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60 * 2,
cacheTime: 1000 * 60 * 10,
retry: 1,
refetchOnWindowFocus: false,
refetchOnReconnect: true,
},
mutations: {
retry: 0,
},
},
})
QueryCache отвечает за хранение и управление состоянием
всех запросов. Через его кастомизацию можно внедрять глобальные побочные
эффекты: логирование, интеграцию с аналитикой, мониторинг ошибок.
import { QueryClient, QueryCache } from '@tanstack/react-query'
const queryClient = new QueryClient({
queryCache: new QueryCache({
onError: (error, query) => {
console.error('Query error:', error)
},
onSuccess: (data, query) => {
console.log('Query success:', query.queryKey)
},
}),
})
const queryCache = new QueryCache({
onError: (error, query) => {
analytics.track('query_error', {
key: query.queryKey,
message: error.message,
})
},
})
MutationCache управляет всеми мутациями (POST, PUT,
DELETE операции). Его настройка особенно важна для контроля побочных
эффектов записи данных.
import { MutationCache } from '@tanstack/react-query'
const mutationCache = new MutationCache({
onError: (error, variables, context, mutation) => {
console.log('Mutation failed:', mutation.options.mutationKey)
},
onSuccess: (data, variables, context, mutation) => {
console.log('Mutation success')
},
})
const mutationCache = new MutationCache({
onSuccess: (data, variables, context, mutation) => {
queryClient.invalidateQueries({ queryKey: ['users'] })
},
})
QueryClient может быть связан с глобальными менеджерами состояния среды: фокус окна и состояние сети.
Контролирует реакцию на переключение вкладок.
import { focusManager } from '@tanstack/react-query'
focusManager.setEventListener((handleFocus) => {
window.addEventListener('visibilitychange', handleFocus)
})
В SSR или нестандартных окружениях (Electron, React Native) можно полностью отключать поведение:
focusManager.setFocused(true)
Управляет состоянием сети.
import { onlineManager } from '@tanstack/react-query'
onlineManager.setEventListener((setOnline) => {
window.addEventListener('online', () => setOnline(true))
window.addEventListener('offline', () => setOnline(false))
})
Можно переопределить поведение для кастомных транспортов (WebSocket, polling API gateway).
В серверном рендеринге важно, чтобы QueryClient создавался изолированно для каждого запроса.
export function createQueryClient() {
return new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60,
retry: false,
},
},
})
}
import { HydrationBoundary } from '@tanstack/react-query'
<HydrationBoundary state={dehydratedState}>
<App />
</HydrationBoundary>
Кастомизация QueryClient часто используется для реализации единой стратегии кеширования:
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 30,
gcTime: 1000 * 60 * 5,
refetchOnWindowFocus: false,
refetchOnReconnect: true,
retry: 1,
structuralSharing: true,
},
},
})
Позволяет переиспользовать неизменённые части данных между рендерами, снижая нагрузку на GC и повышая производительность UI.
QueryClient позволяет внедрять кастомное логирование через cache hooks или обёртки.
const queryClient = new QueryClient({
queryCache: new QueryCache({
onError: (error, query) => {
logger.error('Query failed', {
key: query.queryKey,
error,
})
},
}),
})
Логирование часто используется для:
В сложных приложениях может использоваться несколько QueryClient с разными настройками:
const publicClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60 * 10,
},
},
})
const adminClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 10,
refetchOnWindowFocus: true,
},
},
})
Такой подход позволяет разделять:
Кастомизация QueryClient часто направлена на устранение «магического поведения» запросов. При правильной настройке:
Особенно важны согласованные значения:
staleTimegcTimeretryrefetchOnWindowFocusИх комбинация формирует фундамент модели работы с серверным состоянием в TanStack Query