Capítulo 31 de 80
Every queryFn receives an AbortSignal; consuming it (wiring it into fetch/axios/etc.) makes that query genuinely cancellable — un-consumed signals just leave unmounted/inactive queries running to completion in the background (harmless, since the result still populates the cache for later reuse).
signal: an unmounted or now-inactive query's in-flight Promise is not cancelled — it finishes and its result lands in the cache, ready if the component remounts before GC. This is a feature, not a bug: no wasted work if the user comes right back.signal is passed into the underlying request (fetch(url, { signal }), axios.get(url, { signal }), etc.), the query becomes genuinely abortable, and cancelling reverts its state to what it was before the fetch started.fetch/modern axios (v0.22+) accept signal directly; older axios needs a CancelToken bridged via signal.addEventListener('abort', ...); XMLHttpRequest needs the same abort-listener bridge calling .abort(); graphql-request accepts signal on request() (v4+) or the client constructor (pre-v4).queryClient.cancelQueries({ queryKey }) cancels a query on demand (e.g. from a "Cancel" button) — reverts state, and if signal is consumed, actually aborts the underlying request too.{ silent: true } suppresses CancelledError propagation to onError/observers, returning the retry promise instead of rejecting; { revert: true } (default) restores the pre-fetch data/status and resets fetchStatus to idle — only throwing if there was no prior data to revert to.useSuspenseQuery/useSuspenseQueries/useSuspenseInfiniteQuery.// fetch — pass signal straight through
useQuery({
queryKey: ['todos'],
queryFn: async ({ signal }) => {
const res = await fetch('/todos', { signal })
return res.json()
},
})
// Manual cancel, e.g. from a Cancel button
const queryClient = useQueryClient()
<button onClick={() => queryClient.cancelQueries({ queryKey: ['todos'] })}>Cancel</button>
signal into fetch to make the query genuinely abortable, and triggering that cancellation manually via cancelQueries.signal unconsumed — the default "let it finish, cache it anyway" behavior is intentional, not a gap.signal through whenever a request is expensive/slow enough that an abandoned navigation should actually stop it server-side, not just client-side.cancelQueries there.signal arrives via the same QueryFunctionContext covered there.cancelQueries is a required first step before an optimistic setQueryData write.