QueryClient является центральным объектом в архитектуре TanStack Query и представляет собой контейнер для управления всем состоянием серверных данных, кэшем запросов, стратегиями обновления и механизмами синхронизации. Именно через QueryClient библиотека координирует выполнение запросов, хранение результатов, инвалидизацию данных и фоновые обновления.
В основе TanStack Query лежит идея разделения серверного и клиентского состояния. QueryClient выступает как слой управления серверным состоянием, объединяя:
Каждый запрос, созданный через useQuery или fetchQuery, регистрируется внутри QueryClient и становится частью глобального кэша.
Базовая инициализация выполняется через конструктор QueryClient:
import { QueryClient } from '@tanstack/react-query'
const queryClient = new QueryClient()
В этом случае используется конфигурация по умолчанию, которая подходит для большинства простых приложений, но редко достаточна для production-систем.
Основная сила QueryClient заключается в возможности централизованной настройки поведения всех запросов через query defaults.
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: 2,
staleTime: 1000 * 60,
cacheTime: 1000 * 60 * 10,
refetchOnWindowFocus: true,
refetchOnReconnect: true,
},
mutations: {
retry: 1,
},
},
})
staleTime
Определяет время, в течение которого данные считаются свежими. Пока данные свежие, повторный запрос не выполняется.
staleTime: 1000 * 30
cacheTime
Определяет, как долго неиспользуемые данные остаются в памяти до удаления.
cacheTime: 1000 * 60 * 5
retry
Определяет количество автоматических повторов при ошибке запроса.
retry: 3
Также может быть функцией:
retry: (failureCount, error) => {
return failureCount < 2
}
refetchOnWindowFocus
Автоматическое обновление данных при возврате фокуса на вкладку.
refetchOnWindowFocus: true
Это поведение особенно важно для данных, которые часто изменяются (дашборды, аналитика, чаты).
refetchOnReconnect
Запуск повторного запроса при восстановлении интернет-соединения.
refetchOnReconnect: true
Mutations управляют изменением серверных данных. Их глобальная конфигурация задается отдельно:
mutations: {
retry: 0,
}
В отличие от queries, mutations чаще всего не повторяются автоматически, так как могут приводить к дублирующим операциям (например, повторная отправка формы).
QueryClient сам по себе не активен без подключения к React-дереву через провайдер:
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
const queryClient = new QueryClient()
function App() {
return (
<QueryClientProvider client={queryClient}>
<YourApp />
</QueryClientProvider>
)
}
QueryClientProvider передает экземпляр клиента во все хуки TanStack Query через React Context. Это позволяет любому компоненту получать доступ к кэшу и методам управления данными.
QueryClient предоставляет API для прямого управления кэшем и запросами.
Позволяет синхронно получить данные из кэша:
const data = queryClient.getQueryData(['todos'])
Метод не инициирует запрос, а только читает кэш.
Позволяет вручную изменить данные в кэше:
queryClient.setQueryData(['todos'], old => {
return [...old, { id: 1, title: 'New todo' }]
})
Используется для оптимистичных обновлений.
Отмечает запросы как устаревшие и запускает их повторную загрузку:
queryClient.invalidateQueries({
queryKey: ['todos'],
})
Это ключевой механизм синхронизации данных после мутаций.
Принудительно перезапрашивает данные:
queryClient.refetchQueries({
queryKey: ['todos'],
})
В отличие от invalidateQueries, не зависит от staleTime.
Удаляет данные из кэша:
queryClient.removeQueries({
queryKey: ['todos'],
})
Полезно для очистки данных при logout.
QueryClient позволяет реализовать централизованную стратегию работы с серверными данными.
queryClient.clear()
Удаляет все queries и mutations из памяти.
QueryClient может заранее загрузить данные до рендера компонентов:
await queryClient.prefetchQuery({
queryKey: ['todos'],
queryFn: fetchTodos,
})
Это используется для SSR и ускорения загрузки интерфейса.
const data = await queryClient.fetchQuery({
queryKey: ['user'],
queryFn: fetchUser,
})
QueryClient позволяет управлять стратегией хранения данных через единые правила.
Определяет время жизни неиспользуемых данных:
gcTime: 1000 * 60 * 10
После истечения времени данные удаляются из памяти.
QueryClient используется совместно с devtools для отладки:
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
Devtools позволяют визуализировать:
Технически возможно создать несколько экземпляров QueryClient, но это требует строгой изоляции контекстов:
const clientA = new QueryClient()
const clientB = new QueryClient()
Используется в сложных системах с микрофронтендами или независимыми приложениями.
QueryClient задает базовые правила, но каждый useQuery может их переопределить:
useQuery({
queryKey: ['todos'],
queryFn: fetchTodos,
staleTime: 1000 * 10,
})
Приоритет всегда отдается локальной конфигурации над глобальной.
Одной из частых проблем является чрезмерно агрессивное кэширование:
Другой распространенный сценарий — отсутствие централизованной стратегии инвалидизации, что приводит к рассинхронизации данных между компонентами.
QueryClient фактически выполняет роль lightweight data layer внутри frontend-приложения. Он заменяет необходимость вручную управлять:
В результате приложение переходит от императивного управления данными к декларативной модели, где QueryClient определяет правила, а не последовательность действий.