Кэш RTK Query строится вокруг нормализованного хранения результатов
запросов по ключу endpoint + аргументы. Каждый запрос
сохраняется как отдельная запись, к которой привязываются подписчики
компонентов. Пока существует хотя бы одна активная подписка, данные
считаются актуальными и удерживаются в памяти.
Принудительная очистка кэша становится необходимой в ситуациях, когда стандартные механизмы инвалидации (tags, refetch, refetchOnMount) не покрывают жизненный цикл данных. Типичные случаи включают:
RTK Query хранит данные в нескольких слоях:
queries — результаты конкретных запросовmutations — состояние мутацийprovidedTags — таблица тегов для инвалидацииsubscriptions — активные подписки компонентовconfig — настройки API-слайсаПринудительное вмешательство может затронуть как отдельные записи, так и весь API-слайс целиком. Это важно, потому что частичная очистка не всегда приводит к повторному запросу данных — поведение зависит от наличия подписчиков.
Основной механизм полного сброса состояния —
resetApiState. Он возвращает API slice к начальному
состоянию, как будто запросов никогда не выполнялось.
import { api } from './apiSlice';
import { store } from './store';
store.dispatch(api.util.resetApiState());
После выполнения:
queriesmutationsprovidedTagsКлючевая особенность — это именно «жёсткий» сброс. Даже активные компоненты теряют данные и инициируют повторные запросы при следующем рендере.
Более точечный механизм — удаление одного кэширующего ключа:
store.dispatch(
api.util.removeQueryResult('getUser', { id: 5 })
);
Это действие:
queriesЕсли в момент удаления существует активная подписка, RTK Query может немедленно выполнить повторный запрос, так как данные считаются отсутствующими.
Хотя tag-based система не является прямой очисткой, она часто используется как мягкая форма принудительного обновления.
getUser: builder.query({
query: (id) => `user/${id}`,
providesTags: (result, error, id) => [{ type: 'User', id }]
})
И последующая инвалидация:
store.dispatch(
api.util.invalidateTags([{ type: 'User', id: 5 }])
);
Поведение:
Это важное отличие от removeQueryResult, где данные
исчезают немедленно.
Кэш RTK Query тесно связан с подписками. Если компонент
размонтирован, но запрос всё ещё закэширован, данные сохраняются до
истечения keepUnusedDataFor.
createApi({
reducerPath: 'api',
keepUnusedDataFor: 60
})
Принудительная очистка часто комбинируется с управлением подписками:
removeQueryResultresetApiStateВажно учитывать, что даже после удаления данных подписка может быть
пересоздана автоматически при повторном использовании хука
useQuery.
RTK Query не предоставляет отдельного метода «force clear and refetch», но аналогичный эффект достигается комбинацией:
dispatch(api.util.invalidateTags(['User']));
или через изменение аргументов запроса:
useGetUserQuery({ id: userId }, { refetchOnMountOrArgChange: true });
Изменение аргумента приводит к:
В SPA с авторизацией часто возникает необходимость полного сброса API состояния при logout:
const logout = () => {
dispatch(authSlice.actions.logout());
dispatch(api.util.resetApiState());
};
Такой подход предотвращает:
Иногда дополнительно очищаются persisted store (если используется redux-persist), иначе кэш может восстановиться после reload.
RTK Query позволяет вмешиваться через middleware-уровень, где можно перехватывать события и удалять кэш выборочно:
const apiCleanupMiddleware = (store) => (next) => (action) => {
if (action.type === 'auth/logout') {
store.dispatch(api.util.resetApiState());
}
return next(action);
};
Также возможна интеграция с бизнес-логикой:
При очистке кэша важно учитывать состояние активных запросов:
pending, он может завершиться
уже после удаления записиЭто создаёт эффект «гонки состояния», особенно при массовом
resetApiState.
Чрезмерное использование полной очистки приводит к:
Поэтому часто применяется комбинированная стратегия:
invalidateTags для обновления данныхremoveQueryResult для точечных случаевresetApiState только для глобальных событийkeepUnusedDataFor для контроля времени жизни кэшаПосле принудительной очистки RTK Query восстанавливает кэш постепенно:
useQuery создаёт новый entryqueriesТаким образом система возвращается в исходное состояние без необходимости перезагрузки приложения, сохраняя архитектуру реактивного кэширования даже после полного сброса данных.