TanStack Query рассматривает каждый запрос как объект с четко определённым жизненным циклом. Вместо ручного управления флагами загрузки, ошибок и кэширования библиотека предоставляет унифицированную модель состояния, которая описывает текущее положение запроса в системе: от момента инициализации до получения данных, повторных фетчей и инвалидирования.
Основная идея заключается в том, что состояние запроса разделено на две независимые оси: status и fetchStatus. Первая отражает результат выполнения, вторая — текущее поведение сети.
Поле status описывает логическое состояние данных:
Запрос ещё не был запущен. В TanStack Query это встречается редко в
типичных сценариях useQuery, но может появляться при
условных запросах (enabled: false).
Запрос выполняется, данные ещё не получены. В ранних версиях это
состояние называлось loading, но в современных версиях
используется более точная модель.
Запрос завершился успешно, данные получены и сохранены в кэше.
Запрос завершился ошибкой. В состоянии доступны объект ошибки и предыдущие данные (если они были закэшированы).
В отличие от status, поле fetchStatus
отражает не результат, а текущее состояние сетевой операции:
Запрос активно выполняется в данный момент.
Запрос приостановлен. Такое возможно при отсутствии сети, использовании оффлайн-режимов или глобальных конфигураций повторных попыток.
Запрос не выполняет сетевых операций в данный момент.
Ключевой момент архитектуры TanStack Query заключается в том, что наличие данных и состояние сети — разные вещи.
status отвечает на вопрос: «Есть ли у нас валидный
результат?»
fetchStatus отвечает на вопрос: «Что происходит с сетью
прямо сейчас?»
Пример комбинаций:
status: success, fetchStatus: idle —
данные загружены, запрос не активенstatus: success, fetchStatus: fetching —
происходит фоновое обновление (background refetch)status: error, fetchStatus: idle —
последняя попытка завершилась ошибкой, новых запросов нетstatus: pending, fetchStatus: fetching —
первичная загрузкаTanStack Query предоставляет набор вычисляемых флагов, которые упрощают работу с состоянием.
Истинно, когда запрос впервые загружается и данных ещё нет.
Эквивалентно:
status === "pending"Истинно, когда выполняется любой сетевой запрос, независимо от наличия данных.
Это ключевое отличие от isLoading:
isFetching может быть true даже при уже отображённых
данных.
Пример:
isFetching === true, но UI не обязан блокироватьсяУпрощённый доступ к состоянию ошибки.
Эквивалент:
status === "error"Эквивалент:
status === "success"Комбинированное состояние, означающее первую загрузку без данных.
Используется для отображения скелетонов интерфейса.
Поле data содержит результат успешного запроса. Важно
учитывать, что:
status: pending data может быть
undefinedПри status: error здесь находится объект ошибки. Часто
это:
queryFnОтдельно от статусов существует концепция staleTime и логика устаревания данных.
Данные могут находиться в состоянии:
Это влияет на автоматический рефетч при:
Хотя isStale напрямую не является основным флагом
useQuery, он проявляется через поведение кэша и
автоматические обновления.
Сценарий:
Состояние:
status: pendingfetchStatus: fetchingisLoading: trueUI-логика:
Сценарий:
Состояние:
status: successfetchStatus: idleisLoading: falseUI-логика:
Сценарий:
Состояние:
status: successfetchStatus: fetchingisFetching: trueUI-логика:
Сценарий:
Состояние:
status: errorfetchStatus: idleerror содержит причинуdata может сохранять старое значениеUI-логика:
Кэширование влияет на то, какие состояния будут наблюдаться:
isLoadingisFetching используется для обновлений в фонеКлючевая особенность: TanStack Query всегда предпочитает показывать устаревшие данные, чем пустой экран.
При использовании enabled: false:
status часто остаётся idlefetchStatus = idleПосле включения:
pendingПовторные попытки (retry) не меняют базовую модель
статусов, но влияют на fetchStatus:
fetchStatus: fetchingpaused или промежуточные
состоянияХотя состояние доступно через useQuery, визуальный
анализ становится проще через инструменты разработчика TanStack Query
Devtools:
status и fetchStatusЭто позволяет точно понимать поведение системы в сложных сценариях с несколькими запросами.
Распространённая ошибка — блокировка интерфейса при каждом refetch.
isLoading предназначен только для первой загрузки.
Некорректно считать, что status: success означает
отсутствие активности. Фоновый запрос может выполняться параллельно.
TanStack Query допускает ситуацию, когда:
Игнорирование data в этом случае приводит к потере
UX-устойчивости.
Поведение запроса можно формализовать как конечный автомат:
fetchStatus при этом изменяется ортогонально, не нарушая
основной логики переходов.
В сложных интерфейсах состояние запроса редко используется напрямую. Обычно оно преобразуется в UI-модель:
TanStack Query предоставляет базовые сигналы, но конечная композиция всегда зависит от логики отображения и приоритетов данных.