В приложениях с большим количеством запросов быстро появляется
проблема дублирования конфигурации. Одни и те же параметры начинают
повторяться в каждом useQuery:
useQuery({
queryKey: ['users'],
queryFn: fetchUsers,
staleTime: 1000 * 60 * 5,
retry: 2,
refetchOnWindowFocus: false
})
Через некоторое время одинаковые настройки оказываются разбросаны по десяткам компонентов. Это усложняет поддержку, повышает вероятность ошибок и делает поведение запросов непредсказуемым.
TanStack Query решает эту проблему через систему дефолтных опций. Они позволяют централизованно определить базовое поведение всех запросов и мутаций.
Основная идея:
Все глобальные настройки определяются внутри
QueryClient.
Базовый пример:
import { QueryClient } from '@tanstack/react-query'
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60,
retry: 2
}
}
})
После этого все запросы автоматически получают указанные настройки.
Объект defaultOptions делится на две основные
секции:
const queryClient = new QueryClient({
defaultOptions: {
queries: {},
mutations: {}
}
})
Настройки для useQuery, useInfiniteQuery,
fetchQuery, prefetchQuery.
Настройки для useMutation.
Параметр определяет, как долго данные считаются актуальными.
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60 * 5
}
}
})
В примере данные будут считаться свежими 5 минут.
Пока данные свежие:
Значение по умолчанию.
staleTime: 0
Данные мгновенно становятся устаревшими после получения.
Это означает:
В старых версиях параметр назывался cacheTime.
Определяет время хранения неиспользуемых данных в кеше.
const queryClient = new QueryClient({
defaultOptions: {
queries: {
gcTime: 1000 * 60 * 10
}
}
})
После удаления последнего подписчика запрос остаётся в кеше 10 минут.
Если за это время запрос снова понадобится:
gcTime: 0
Кеш будет уничтожаться сразу после потери подписчиков.
Такой подход редко используется, поскольку ухудшает производительность.
Количество повторных попыток при ошибке.
retry: 3
Если запрос завершится ошибкой, TanStack Query автоматически повторит его ещё 3 раза.
retry: false
Полезно для:
Задержка между повторными попытками.
retryDelay: 1000
Фиксированная задержка — 1 секунда.
retryDelay: (attempt) => {
return Math.min(1000 * 2 ** attempt, 30000)
}
Реализуется exponential backoff.
Пример интервалов:
| Попытка | Задержка |
|---|---|
| 1 | 2 сек |
| 2 | 4 сек |
| 3 | 8 сек |
| 4 | 16 сек |
Это снижает нагрузку на сервер.
Автоматический рефетч при возврате на вкладку браузера.
refetchOnWindowFocus: true
Поведение по умолчанию.
refetchOnWindowFocus: false
Часто используется в:
Повторный запрос после восстановления интернет-соединения.
refetchOnReconnect: true
Когда соединение восстанавливается, TanStack Query автоматически синхронизирует данные.
Поведение при монтировании компонента.
refetchOnMount: true
Если данные устарели, произойдёт повторный запрос.
| Значение | Поведение |
|---|---|
| true | Рефетч при stale |
| false | Не выполнять |
| “always” | Всегда выполнять |
Интервальный polling.
refetchInterval: 5000
Запрос будет обновляться каждые 5 секунд.
Используется для:
Разрешает polling в фоне.
refetchIntervalInBackground: true
Без этого polling может приостанавливаться в неактивной вкладке.
Определяет поведение при отсутствии сети.
networkMode: 'online'
| Режим | Описание |
|---|---|
| online | Стандартное поведение |
| always | Игнорирует offline |
| offlineFirst | Поддержка offline-first |
Обычно задаётся локально, но может использоваться и глобально.
enabled: true
Отключение:
enabled: false
Тогда запрос не запускается автоматически.
Позволяет пробрасывать ошибки в Error Boundary.
throwOnError: true
Особенно полезно в React-приложениях с централизованной обработкой ошибок.
Дополнительные метаданные.
meta: {
requiresAuth: true
}
Можно использовать:
const queryClient = new QueryClient({
defaultOptions: {
mutations: {
retry: 1
}
}
})
Мутации обычно не повторяются агрессивно, поскольку это может привести к:
mutations: {
networkMode: 'offlineFirst'
}
Полезно для offline-first приложений.
Мутации тоже кешируются.
mutations: {
gcTime: 1000 * 60 * 30
}
import { QueryClient } from '@tanstack/react-query'
export const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60 * 5,
gcTime: 1000 * 60 * 30,
retry: 2,
retryDelay: (attempt) => {
return Math.min(1000 * 2 ** attempt, 30000)
},
refetchOnWindowFocus: false,
refetchOnReconnect: true,
refetchOnMount: true,
networkMode: 'online'
},
mutations: {
retry: 1,
networkMode: 'online'
}
}
})
Локальные настройки имеют приоритет над глобальными.
useQuery({
queryKey: ['users'],
queryFn: fetchUsers,
staleTime: 0
})
Даже если глобально установлен staleTime: 5 минут, здесь
будет использоваться 0.
Порядок приоритета:
TanStack Query позволяет задавать настройки для конкретных групп запросов.
queryClient.setQueryDefaults(['users'], {
staleTime: 1000 * 60 * 10
})
Теперь все запросы с ключом users получают собственные
дефолтные настройки.
queryClient.setQueryDefaults(['posts'], {
retry: 1
})
Будет применяться к:
['posts']
['posts', 1]
['posts', 'recent']
['posts', 'popular']
Аналогичный механизм существует для мутаций.
queryClient.setMutationDefaults(['create-post'], {
retry: 0
})
queries: {
staleTime: 1000 * 60 * 30,
gcTime: 1000 * 60 * 60
}
Подходит для:
queries: {
staleTime: 0,
refetchOnWindowFocus: true,
refetchOnMount: true
}
Подходит для:
queries: {
networkMode: 'offlineFirst',
retry: 5
}
Используется в PWA и мобильных приложениях.
Слишком большой staleTime может приводить к отображению
устаревших данных.
Проблемные сценарии:
refetchInterval: 1000
Запрос каждую секунду может:
Повторные запросы полезны только для временных ошибок:
Для ошибок вида:
автоматический retry обычно бесполезен.
Часто применяется несколько профилей:
queryClient.setQueryDefaults(['static'], {
staleTime: 1000 * 60 * 60
})
queryClient.setQueryDefaults(['dynamic'], {
staleTime: 0
})
Если настройки не указаны, библиотека использует собственные значения.
Основные встроенные дефолты:
| Параметр | Значение |
|---|---|
| staleTime | 0 |
| retry | 3 |
| gcTime | 5 минут |
| refetchOnWindowFocus | true |
| refetchOnReconnect | true |
| refetchOnMount | true |
Из-за этих дефолтов TanStack Query часто кажется «слишком активным» сразу после подключения.
Обычно QueryClient выносится в отдельный файл:
// lib/query-client.js
import { QueryClient } from '@tanstack/react-query'
export const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60 * 5,
retry: 2
}
}
})
Это позволяет:
Грамотно подобранные дефолты напрямую влияют на:
Неправильная конфигурация может привести к:
По этой причине стратегия дефолтных настроек считается одной из ключевых частей архитектуры приложений на TanStack Query.