React Query cung cấp signal (AbortSignal) qua queryFn context — pass signal vào fetch để enable cancellation: queryFn: ({ signal }) => fetch(/api/users/${id}, { signal }).
Khi component unmount hoặc queryKey thay đổi, React Query tự động abort signal → browser hủy pending request.
Với axios: queryFn: ({ signal }) => axios.get(/api/users/${id}, { signal }) — axios v0.22+ support AbortSignal trực tiếp.
Custom fetch wrapper: async function fetchWithCancel(url, { signal }) { const res = await fetch(url, { signal }); if (!res.ok) throw new Error(res.statusText); return res.json() }.
Cancellation xảy ra khi:
- component unmount trước khi fetch xong (user navigate đi),
- queryKey thay đổi nhanh (search input) — request cũ bị cancel khi key mới,
queryClient.cancelQueries()được gọi manual (thường trong optimistic update onMutate)
Lưu ý: nếu queryFn không dùng signal, query vẫn complete dù component unmount — data được cache nhưng component đã gone, React Query tự discard result.
Không dùng signal gây lãng phí bandwidth nhưng không gây bug.
React Query v5 automatically cancels in-flight queries when: the component unmounts, the query key changes, or a new fetch is triggered while one is already running.
- Manual cancellation is achieved via AbortSignal: the queryFn receives a signal in its context object that fires when React Query cancels the query.
- In the fetch API: queryFn: ({ signal }) => fetch(url, { signal }).
- In axios: queryFn: ({ signal }) => axios.get(url, { signal }).
- React Query v5 uses AbortController internally and passes the signal automatically.
- For imperative cancellation: queryClient.cancelQueries({ queryKey: ['todos'] }) — cancels all ongoing fetches for matching queries and removes them from the in-flight state.
- Proper cancellation prevents race conditions and unnecessary network requests when users navigate quickly.