Polling в RTK Query представляет собой механизм периодического автоматического обновления данных по заранее заданному интервалу времени. Он реализуется на уровне подписки на query и позволяет поддерживать состояние клиента синхронизированным с сервером без ручного вмешательства.
Ключевая особенность polling заключается в том, что он работает только пока существует активная подписка на запрос. Как только последний компонент, использующий query, размонтируется, polling автоматически прекращается. Это напрямую связано с системой кэширования и подписок RTK Query.
Основной способ включения polling — передача параметра
pollingInterval в хук useQuery.
const { data, error, isLoading } = useGetUsersQuery(undefined, {
pollingInterval: 5000
});
Значение задаётся в миллисекундах. В данном примере запрос будет повторяться каждые 5 секунд.
Поведение:
Polling автоматически прекращается при следующих условиях:
skip становится true;unsubscribe на уровне низкоуровневого
API.const query = useGetUsersQuery(undefined, {
pollingInterval: 3000,
skip: isPaused
});
В данном случае polling динамически управляется через состояние
isPaused.
pollingInterval может изменяться во время жизненного
цикла компонента. Это приводит к пересозданию таймера.
const interval = isFastMode ? 2000 : 10000;
useGetUsersQuery(undefined, {
pollingInterval: interval
});
RTK Query корректно пересчитывает интервал без необходимости ручного сброса подписки.
Рефетчинг в RTK Query — это механизм принудительного или условного повторного запроса данных для обновления кэша.
В отличие от polling, который работает автоматически по таймеру, refetching чаще связан с событиями: фокус окна, восстановление соединения, ручной вызов или инвалидация данных.
Каждый query-хук возвращает функцию refetch, которая
инициирует повторный запрос независимо от кэша.
const { data, refetch } = useGetUsersQuery();
<button onCl ick={() => refetch()}>
Обновить данные
</button>
Особенности поведения:
Повторное использование useQuery с теми же аргументами
не всегда вызывает сетевой запрос, так как RTK Query использует
кэширование и дедупликацию.
Refetch же:
RTK Query поддерживает автоматическое обновление данных при возвращении фокуса в окно браузера.
Это управляется параметром:
refetchOnFocus: true
Пример:
useGetUsersQuery(undefined, {
refetchOnFocus: true
});
Механика работы:
В api можно задать поведение по умолчанию:
export const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: "/api" }),
endpoints: (builder) => ({
getUsers: builder.query({
query: () => "/users"
})
}),
refetchOnFocus: true
});
Это позволяет централизованно управлять стратегией обновления данных.
RTK Query может автоматически повторять запросы при восстановлении интернет-соединения.
useGetUsersQuery(undefined, {
refetchOnReconnect: true
});
Поведение:
online;Комбинация refetchOnFocus и
refetchOnReconnect часто используется для обеспечения
актуальности данных в SPA.
Polling и refetching не конфликтуют, но могут пересекаться по времени выполнения запросов.
Polling активен, происходит refetch вручную → ручной запрос выполняется независимо, polling продолжает работать по таймеру
Refetch совпадает с polling-интервалом → возможна дедупликация, если запрос идентичен и уже выполняется
refetchOnFocus с polling → после возврата фокуса выполняется дополнительный запрос, затем продолжается polling
RTK Query избегает одновременного выполнения идентичных запросов:
В таких случаях второй запрос может быть объединён с первым.
В некоторых случаях требуется игнорировать кэш даже при совпадении данных.
dispatch(
api.endpoints.getUsers.initiate(undefined, {
forceRefetch: true
})
);
Это поведение:
selectFromResult позволяет управлять зависимостью от
части состояния и триггерить повторные запросы через изменение
селектора.
const { data } = useGetUsersQuery(undefined, {
selectFromResult: ({ data }) => ({
data: data?.filter(user => user.active)
})
});
Хотя это не прямой механизм refetch, изменение селектора влияет на подписку и может косвенно приводить к обновлению данных при изменении аргументов или состояния кэша.
Polling тесно связан с жизненным циклом подписки:
RTK Query не использует глобальные таймеры без активных подписок, что снижает нагрузку на приложение.
Если один endpoint используется в нескольких компонентах:
useGetUsersQuery(undefined, { pollingInterval: 5000 });
useGetUsersQuery(undefined, { pollingInterval: 5000 });
RTK Query:
Если интервалы отличаются:
useGetUsersQuery(undefined, { pollingInterval: 2000 });
useGetUsersQuery(undefined, { pollingInterval: 10000 });
Приоритет получает наименьший интервал (наиболее частое обновление), так как он обеспечивает более свежие данные для всех подписчиков.
skip полностью отключает запрос и polling:
useGetUsersQuery(undefined, {
skip: !isAuthorized,
pollingInterval: 5000
});
При skip = true:
RTK Query позволяет комбинировать несколько механизмов актуализации данных:
Типичная конфигурация:
useGetUsersQuery(undefined, {
pollingInterval: 10000,
refetchOnFocus: true,
refetchOnReconnect: true
});
Такой набор создаёт модель, при которой данные обновляются:
При активном polling и refetching:
isFetching отражает текущую активность
запроса.Это позволяет UI оставаться стабильным даже при частых обновлениях данных.