Управление реконнектом

TanStack Query рассматривает сетевой слой как нестабильную среду, где разрывы соединения, переключения сети, уход приложения в фон и возврат пользователя являются нормальными сценариями, а не исключениями. Управление реконнектом в этой библиотеке строится вокруг идеи автоматического восстановления данных и предсказуемого поведения запросов при восстановлении соединения.

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

Ключевые события, на которые опирается механизм реконнекта:

  • window.online — восстановление соединения
  • window.offline — потеря соединения
  • фокус окна (focus/refetch behavior)
  • повторные попытки запросов (retry logic)

При переходе браузера в офлайн-режим библиотека не останавливает внутренние процессы, но временно откладывает выполнение сетевых операций. Как только соединение восстанавливается, активируется механизм рефетча.

Основной механизм восстановления запросов

TanStack Query использует стратегию «event-driven refetch». Это означает, что при наступлении определённых событий происходит автоматический запуск повторных запросов:

  • восстановление сети
  • возврат фокуса на вкладку
  • монтирование компонентов с устаревшими данными
  • истечение времени staleTime (косвенно влияет на реконнект-логику)

Основной триггер реконнекта — событие online. В этот момент QueryClient инициирует перебор активных запросов и проверяет их состояние.

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      refetchOnReconnect: true,
    },
  },
});

Опция refetchOnReconnect определяет, будет ли происходить автоматический рефетч при восстановлении сети.

Управление поведением через refetchOnReconnect

Глобальная настройка

Глобальное управление осуществляется через QueryClient:

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      refetchOnReconnect: true,
    },
  },
});

Локальная настройка запроса

Поведение может быть переопределено на уровне конкретного запроса:

useQuery({
  queryKey: ['user'],
  queryFn: fetchUser,
  refetchOnReconnect: false,
});

При отключении параметра запросы не будут автоматически обновляться при восстановлении сети, даже если данные устарели.

Retry-механизм как часть реконнекта

Реконнект в TanStack Query тесно связан с системой повторных попыток. Если запрос был прерван из-за отсутствия сети, он может быть повторён в соответствии с настройками retry.

useQuery({
  queryKey: ['posts'],
  queryFn: fetchPosts,
  retry: 3,
});

Поведение retry зависит от типа ошибки. Сетевые ошибки рассматриваются как временные и обычно приводят к повторным попыткам. При этом реконнект может «разблокировать» очередь запросов, позволяя retry завершиться успешно.

Функциональный контроль retry

useQuery({
  queryKey: ['data'],
  queryFn: fetchData,
  retry: (failureCount, error) => {
    if (error.status === 404) return false;
    return failureCount < 3;
  },
});

Такой подход позволяет разделять критические и временные ошибки, что особенно важно при нестабильной сети.

Поведение при офлайн-режиме

Когда браузер переходит в offline, TanStack Query:

  • приостанавливает новые запросы
  • сохраняет состояние текущих запросов
  • продолжает хранить кешированные данные
  • фиксирует ошибки только после исчерпания retry

Запросы не удаляются и не инвалидируются автоматически, что позволяет избежать потери состояния интерфейса.

Особенность поведения заключается в том, что библиотека не «забывает» неудачные запросы. Они остаются в состоянии error или paused до восстановления соединения.

Интеграция с фокусом окна

Реконнект часто сопровождается возвратом пользователя к вкладке. TanStack Query объединяет эти два сигнала:

  • refetchOnReconnect
  • refetchOnWindowFocus
useQuery({
  queryKey: ['profile'],
  queryFn: fetchProfile,
  refetchOnWindowFocus: true,
  refetchOnReconnect: true,
});

Если соединение восстанавливается и пользователь возвращается в приложение, может произойти двойной триггер рефетча. TanStack Query предотвращает избыточные запросы, используя внутреннюю дедупликацию.

Дедупликация запросов при реконнекте

Во время восстановления сети может возникнуть ситуация, когда несколько компонентов инициируют один и тот же запрос. TanStack Query использует внутренний механизм dedupe:

  • одинаковые queryKey объединяются
  • повторные запросы игнорируются, если уже выполняется активный fetch
  • результат разделяется между подписчиками

Это особенно важно при массовом рефетче после offline/online перехода.

Поведение staleTime и его влияние на реконнект

Параметр staleTime определяет, считается ли данные устаревшими:

useQuery({
  queryKey: ['settings'],
  queryFn: fetchSettings,
  staleTime: 1000 * 60,
});

Если данные не устарели, реконнект может не вызвать рефетч, даже при refetchOnReconnect: true. Это снижает нагрузку на сервер после кратковременных разрывов сети.

Таким образом, реконнект не является абсолютным триггером — он зависит от состояния кэша.

Управление через focusManager и onlineManager

Внутренне TanStack Query использует два менеджера:

  • onlineManager — отслеживает состояние сети
  • focusManager — отслеживает активность окна

onlineManager

Позволяет вручную управлять состоянием сети:

import { onlineManager } from '@tanstack/react-query';

onlineManager.setEventListener((setOnline) => {
  window.addEventListener('online', () => setOnline(true));
  window.addEventListener('offline', () => setOnline(false));
});

Можно также вручную переключать состояние:

onlineManager.setOnline(false);

Это используется в тестах или при кастомной логике подключения.

Поведение при нестабильной сети

При частых переключениях offline/online TanStack Query:

  • не запускает бесконечные циклы рефетча
  • использует debounce на уровне внутренних событий
  • объединяет события реконнекта в единый триггер

Если сеть нестабильна, запросы могут быть отложены до момента стабилизации состояния online.

Отключение автоматического реконнекта

В некоторых архитектурах требуется полный контроль над сетевыми запросами:

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      refetchOnReconnect: false,
      retry: false,
    },
  },
});

В этом режиме библиотека перестаёт автоматически реагировать на восстановление соединения. Все повторные запросы должны инициироваться вручную через invalidateQueries или refetchQueries.

Взаимодействие с мутациями при реконнекте

Мутации ведут себя отдельно от query-слоя, но могут использовать общие retry-механизмы:

useMutation({
  mutationFn: updateUser,
  retry: 2,
});

При восстановлении сети незавершённые мутации не «перезапускаются» автоматически. Однако можно построить собственную очередь мутаций поверх TanStack Query, используя offlineManager или сторонние очереди задач.

Кэш и восстановление данных после реконнекта

Ключевой принцип работы:

  • кэш сохраняется независимо от сети
  • реконнект лишь инициирует обновление, но не восстановление кэша
  • данные из кэша доступны мгновенно до завершения refetch

Это позволяет интерфейсу оставаться стабильным даже при длительных разрывах соединения.

Практическая модель поведения реконнекта

Типичный сценарий:

  1. Пользователь теряет соединение
  2. Запросы переходят в состояние retry/paused
  3. UI продолжает отображать кэшированные данные
  4. Сеть восстанавливается
  5. onlineManager генерирует событие
  6. QueryClient инициирует refetch для активных запросов
  7. Результаты обновляют кэш
  8. UI синхронизируется без перезагрузки страницы

Такая модель исключает необходимость ручного контроля сетевого состояния в большинстве приложений.

Контроль избыточных обновлений

При реконнекте возможны всплески сетевой активности. Для их ограничения используются:

  • staleTime
  • refetchOnWindowFocus
  • refetchOnReconnect
  • enabled
  • queryKey сегментация

Комбинация этих параметров позволяет тонко регулировать поведение системы при восстановлении соединения и избежать перегрузки API.

Архитектурная роль реконнекта

Механизм реконнекта в TanStack Query выполняет не только техническую, но и архитектурную функцию. Он превращает сетевую нестабильность в управляемое состояние приложения, в котором:

  • данные остаются консистентными
  • пользовательский интерфейс не деградирует
  • повторные запросы централизованы
  • нет необходимости вручную отслеживать connectivity state

Это делает реконнект не отдельной функцией, а частью общей модели реактивного кэширования данных.