Кеш в TanStack Query хранит результаты запросов, состояние загрузки, ошибки и метаданные. Со временем часть данных становится ненужной:
Для подобных сценариев TanStack Query предоставляет механизмы удаления данных из кеша.
Удаление данных отличается от инвалидирования. Инвалидация помечает данные устаревшими и может инициировать повторную загрузку, тогда как удаление полностью уничтожает запись из кеша.
Очень важно понимать различие между двумя подходами.
queryClient.invalidateQueries({
queryKey: ['posts']
});
Поведение:
queryClient.removeQueries({
queryKey: ['posts']
});
Поведение:
Основной метод удаления кеша:
queryClient.removeQueries();
Такой вызов удаляет все запросы из кеша.
На практике обычно используются фильтры.
queryClient.removeQueries({
queryKey: ['user']
});
Удаляется только запрос:
['user']
queryClient.removeQueries({
queryKey: ['posts']
});
Будут удалены:
['posts']
['posts', 1]
['posts', 2]
['posts', 'popular']
Поскольку TanStack Query использует частичное совпадение ключей.
queryClient.removeQueries({
queryKey: ['posts'],
exact: true
});
Теперь удаляется только:
['posts']
Но не:
['posts', 1]
['posts', 'popular']
Для сложной логики применяется predicate.
queryClient.removeQueries({
predicate: (query) => {
return query.queryKey[0] === 'posts';
}
});
queryClient.removeQueries({
predicate: (query) => {
return query.queryKey[0] === 'posts'
&& query.queryKey[1]?.archived === true;
}
});
В кеше могут храниться запросы, которые больше не используются компонентами.
queryClient.removeQueries({
queryKey: ['posts'],
type: 'inactive'
});
Удаляются только неактивные запросы.
Активные запросы продолжают существовать.
queryClient.removeQueries({
queryKey: ['posts'],
type: 'active'
});
Обычно такой подход используется редко, поскольку активные запросы используются компонентами.
Один из самых распространённых сценариев.
const logout = async () => {
await api.logout();
queryClient.removeQueries();
};
После выхода пользователя:
TanStack Query предоставляет ещё один метод.
queryClient.clear();
Разница:
| Метод | Поведение |
|---|---|
| removeQueries | удаляет только запросы |
| clear | очищает QueryCache и MutationCache |
queryClient.clear();
Удаляются:
Это полный сброс клиента.
По умолчанию TanStack Query автоматически очищает неиспользуемые запросы через gcTime.
Например:
const queryClient = new QueryClient({
defaultOptions: {
queries: {
gcTime: 1000 * 60 * 5
}
}
});
Через 5 минут неактивный запрос удалится автоматически.
Но removeQueries позволяет удалить данные немедленно.
Infinite Query хранится как обычный query.
queryClient.removeQueries({
queryKey: ['feed']
});
Удаляются:
Очень важный сценарий для многопользовательских приложений.
const switchAccount = async (userId) => {
await auth.loginAs(userId);
queryClient.clear();
};
Без очистки возможно появление данных предыдущего пользователя.
Некоторые данные нельзя долго хранить в памяти:
queryClient.removeQueries({
queryKey: ['bank-account']
});
Иногда данные нужны только временно.
const finishRegistration = async () => {
await completeRegistration();
queryClient.removeQueries({
queryKey: ['registration-draft']
});
};
В корпоративных системах часто используется контекст проекта или workspace.
const switchWorkspace = async (workspaceId) => {
setWorkspace(workspaceId);
queryClient.removeQueries({
queryKey: ['workspace-data']
});
};
Ключевая особенность метода.
queryClient.removeQueries({
queryKey: ['posts']
});
Запрос не перезагружается автоматически.
Данные просто исчезают.
Новая загрузка произойдёт только если:
Предположим:
useQuery({
queryKey: ['posts'],
queryFn: fetchPosts
});
Если выполнить:
queryClient.removeQueries({
queryKey: ['posts']
});
то:
Если запрос активен:
queryClient.removeQueries({
queryKey: ['posts']
});
то React-компоненты могут сразу инициировать повторную загрузку, потому что данные исчезли.
Поэтому удаление активных запросов требует осторожности.
Наиболее распространённый вариант:
queryClient.removeQueries({
type: 'inactive'
});
Такой подход:
Иногда применяется комбинация.
queryClient.invalidateQueries({
queryKey: ['posts']
});
queryClient.removeQueries({
queryKey: ['draft-posts']
});
Где:
const deleteAccountMutation = useMutation({
mutationFn: deleteAccount,
onSuccess: () => {
queryClient.clear();
}
});
После удаления аккаунта весь кеш очищается.
removeQueries использует систему Query Filters.
queryClient.removeQueries({
queryKey: ['posts'],
exact: true,
type: 'inactive',
stale: true,
predicate: (query) => true
});
Можно удалять только устаревшие запросы.
queryClient.removeQueries({
stale: true
});
Полезно при агрессивной очистке памяти.
queryClient.removeQueries({
predicate: (query) => {
return query.queryKey[0] === 'admin';
}
});
queryClient.removeQueries({
predicate: (query) => {
return query.queryKey.includes('v1');
}
});
При использовании persister необходимо учитывать:
window.addEventListener('session-expired', () => {
queryClient.clear();
});
const handleUnauthorized = () => {
queryClient.clear();
};
Обычно используется после HTTP 401.
В больших приложениях кеш делится по доменам:
['auth']
['posts']
['comments']
['profile']
['notifications']
Это позволяет удалять только нужную область данных.
queryClient.removeQueries({
queryKey: ['notifications']
});
Подходит для:
queryClient.clear();
Подходит для большинства приложений.
queryClient.removeQueries({
type: 'inactive'
});
Используется для конкретных сущностей.
queryClient.removeQueries({
queryKey: ['draft']
});
Удаление предпочтительнее если:
Инвалидация предпочтительнее если:
queryClient.removeQueries({
queryKey: ['posts']
});
Может вызывать лишние refetch.
queryClient.clear();
Полностью уничтожает состояние клиента и mutations.
Для локальной очистки это слишком агрессивный подход.
Плохой вариант:
['data']
Хороший вариант:
['posts']
['posts', id]
['posts', 'drafts']
Структурированные ключи позволяют безопасно очищать кеш.
['auth']
['profile']
['posts']
['posts', postId]
['notifications']
['drafts']
const logout = async () => {
await api.logout();
queryClient.clear();
};
queryClient.removeQueries({
queryKey: ['drafts']
});
queryClient.removeQueries({
queryKey: ['notifications'],
type: 'inactive'
});
При removeQueries:
После этого query перестаёт существовать внутри кеша TanStack Query.