Перейти к содержимому

4. Query: кэширование

TanStack Query автоматически кэширует результаты запросов. Понимание жизненного цикла кэша — ключ к правильной настройке производительности приложения.

Данные в кэше TanStack Query могут находиться в одном из состояний:

Данные только что получены и считаются актуальными. TanStack Query не будет делать новый запрос, даже если компонент перемонтируется или окно получит фокус. Продолжительность — staleTime.

Данные есть в кэше, но уже могли устареть. TanStack Query автоматически обновит их в фоне при следующем обращении (фокус окна, монтирование компонента, переключение вкладок).

Компоненты, использующие данные, размонтированы. Данные ещё хранятся в кэше в течение gcTime.

Данные удалены из кэша после истечения gcTime. Следующий запрос будет выполнен с нуля.

useQuery({
queryKey: ['users'],
queryFn: getUsers,
staleTime: 1000 * 60 * 5, // 5 минут
})
  • По умолчанию: 0 (данные устаревают мгновенно после получения)
  • При staleTime: Infinity данные никогда не устаревают автоматически
  • Хорошие значения: 1-5 минут для часто меняющихся данных, Infinity для статичных (например, список стран)
useQuery({
queryKey: ['users'],
queryFn: getUsers,
gcTime: 1000 * 60 * 10, // 10 минут (было cacheTime в v3)
})
  • По умолчанию: 5 минут
  • Отсчёт начинается когда запрос становится неактивным (нет подписчиков)
  • gcTime должен быть >= staleTime (иначе данные удалятся раньше, чем устареют)

Когда данные устарели (stale), но ещё в кэше, TanStack Query показывает старые данные мгновенно и одновременно делает фоновый запрос за новыми. Это обеспечивает моментальный отклик интерфейса.

const { data, isFetching, isStale } = useQuery(...)
// data — старые данные (показываем сразу)
// isFetching === true — идёт фоновый запрос
// isStale === true — данные устарели

По умолчанию TanStack Query обновляет устаревшие данные при фокусе вкладки браузера. Имитирует поведение нативных приложений — данные всегда актуальны.

// Отключить для всего приложения
const queryClient = new QueryClient({
defaultOptions: { queries: { refetchOnWindowFocus: false } }
})
// Отключить для конкретного запроса
useQuery({ ..., refetchOnWindowFocus: false })