Pass one signal through related requests, distinguish unmounting from actual cancellation, and recognize the Suspense limitation.
Receiving a signal does not automatically abort the network
Query supplies an AbortSignal to queryFn, but an unused request may still complete and populate the cache by default. Cancellation aborts the promise and restores prior Query state only when the request layer consumes the signal.
Carry one signal through the whole request chain
Native fetch accepts signal directly. Check response.ok before parsing JSON, and pass the same signal to every related request made by one queryFn so only part of the chain is not left running.
import { queryOptions } from '@tanstack/react-query'
export const issuesOptions = queryOptions({
queryKey: ['issues', 'list'] as const,
queryFn: async ({ signal }) => {
const response = await fetch('/api/issues', { signal })
if (!response.ok) throw new Error('Unable to load issues')
return response.json()
},
})Turn this lesson into a verifiable skill
One Query AbortSignal reaches the entire request chain, stopping obsolete I/O without disguising cancellation as success.
Cancel the previous detail request during rapid issue switching and handle AbortError differently from a network failure.
Switch routes rapidly on a slow network; the old request should cancel, the new one should finish, and empty data should not flash.
- Receiving signal without passing it to fetch.
- Catching cancellation and returning an empty array, causing Query to report success.