Доки по разработке
This project is maintained by teniryte
Инвалидация сообщает TanStack Query, что данные больше нельзя считать актуальными. Это основной механизм синхронизации query cache после мутаций, сокет-событий и внешних изменений.
invalidateQueriesawait queryClient.invalidateQueries({
queryKey: ['todos'],
})
Что происходит:
await queryClient.invalidateQueries({
queryKey: ['todos'],
exact: false,
refetchType: 'active',
})
refetchType:
active обновляет только то, что сейчас используется на экранеinactive обновляет только фоновый кешall обновляет всёrefetchQueriesЕсли вы хотите именно принудительный рефетч, а не просто маркировку stale:
await queryClient.refetchQueries({
queryKey: ['todos'],
type: 'active',
})
На практике чаще нужен invalidateQueries, а не refetchQueries.
cancelQueriesПеред optimistic update почти всегда сначала:
await queryClient.cancelQueries({ queryKey: ['todos'] })
Зачем:
setQueryData и внешние событияЕсли данные пришли из WebSocket, SSE или BroadcastChannel:
queryClient.setQueryData(['todos', 'detail', todo.id], todo)
Это лучше, чем немедленно дёргать сеть ещё раз.
Частый production-паттерн:
setQueryDataStale-запросы по умолчанию рефетчатся:
Это одна из самых важных “магий” библиотеки. Если команда не знает об этих триггерах, поведение может казаться случайным.
staleTime как главный рычагuseQuery({
queryKey: ['feed'],
queryFn: fetchFeed,
staleTime: 2 * 60_000,
})
Чем больше staleTime, тем меньше автоматических рефетчей.
Вместо рефлекса “отключить всё” чаще достаточно просто осмысленно поднять staleTime.
useQuery({
queryKey: ['build-status', buildId],
queryFn: () => fetchBuildStatus(buildId),
refetchInterval: (query) =>
query.state.data?.finished ? false : 5_000,
})
Это удобнее, чем ручной setInterval.
refetchOnWindowFocus, refetchOnMount, refetchOnReconnectЭти флаги не заменяют staleTime, а дополняют его.
Типовые настройки:
useQuery({
queryKey: ['profile'],
queryFn: fetchProfile,
staleTime: 5 * 60_000,
refetchOnWindowFocus: false,
})
Подходит, если вкладка часто теряет фокус, а данные не критичны.
useMutation({
mutationFn: updateTodo,
onSuccess: (_data, variables) => {
return queryClient.invalidateQueries({
queryKey: ['todos', 'detail', variables.id],
})
},
})
Если затронуты и detail, и list:
await Promise.all([
queryClient.invalidateQueries({ queryKey: ['todos', 'detail', id] }),
queryClient.invalidateQueries({ queryKey: ['todos', 'list'] }),
])
removeQueries, resetQueries, clearЭто не одно и то же:
removeQueries удаляет совпадающие записиresetQueries сбрасывает состояние запросаclear очищает весь клиентТипичный случай для clear: logout с полной сменой пользователя.
window.location.reload().staleTime, прежде чем массово отключать refetch triggers.setQueryData и инвалидируйте только когда нужна полная серверная сверка.