6. Query: инвалидация кэша
Зачем инвалидировать кэш?
Заголовок раздела «Зачем инвалидировать кэш?»После мутации данные на сервере изменились, но TanStack Query не знает об этом. Инвалидация сообщает библиотеке: «эти данные устарели, нужно их обновить». При следующем обращении к кэшу автоматически выполнится новый запрос.
queryClient.invalidateQueries
Заголовок раздела «queryClient.invalidateQueries»Самый распространённый способ обновить данные после мутации:
const queryClient = useQueryClient()
// Инвалидировать все запросы с ключом 'users'queryClient.invalidateQueries({ queryKey: ['users'] })
// Инвалидировать конкретного пользователяqueryClient.invalidateQueries({ queryKey: ['user', userId] })
// Инвалидировать всё что начинается с 'user' (включая ['user', 1], ['users', 'list'])queryClient.invalidateQueries({ queryKey: ['user'] })
// Инвалидировать ВСЕ запросыqueryClient.invalidateQueries()Точность инвалидации
Заголовок раздела «Точность инвалидации»TanStack Query использует иерархическое сопоставление ключей:
queryClient.invalidateQueries({ queryKey: ['users'] })// Инвалидирует: ['users'], ['users', 1], ['users', { filter: 'active' }]
queryClient.invalidateQueries({ queryKey: ['users', 1] })// Инвалидирует ТОЛЬКО: ['users', 1]// НЕ инвалидирует: ['users'], ['users', 2]refetchQueries: Принудительное обновление
Заголовок раздела «refetchQueries: Принудительное обновление»refetchQueries немедленно запускает запрос, не дожидаясь обращения к кэшу:
// Принудительно обновить сейчасawait queryClient.refetchQueries({ queryKey: ['users'] })
// Только активные запросы (есть подписчики)await queryClient.refetchQueries({ queryKey: ['users'], type: 'active' })setQueryData: Обновление кэша вручную
Заголовок раздела «setQueryData: Обновление кэша вручную»Позволяет напрямую установить данные в кэш без запроса. Ключевой инструмент для оптимистичных обновлений:
// Установить данныеqueryClient.setQueryData(['user', 1], { id: 1, name: 'Новое имя' })
// Обновить данные (как setState с функцией)queryClient.setQueryData(['users'], (oldData: User[]) => { return oldData.map(user => user.id === updatedUser.id ? updatedUser : user )})getQueryData: Чтение кэша
Заголовок раздела «getQueryData: Чтение кэша»const users = queryClient.getQueryData<User[]>(['users'])const user = queryClient.getQueryData<User>(['user', 1])cancelQueries: Отмена запросов
Заголовок раздела «cancelQueries: Отмена запросов»Полезно перед оптимистичным обновлением — отменяем текущий запрос, чтобы не перезаписать наши изменения:
await queryClient.cancelQueries({ queryKey: ['users'] })removeQueries: Удаление из кэша
Заголовок раздела «removeQueries: Удаление из кэша»queryClient.removeQueries({ queryKey: ['user', oldUserId] })