AbortController for Cleanup
Create an AbortController, pass its signal to fetch, and cancel in-flight requests in the cleanup function to prevent state updates on unmounted components.
AbortController for Cleanup is a free Frontend Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Frontend Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why Cancel Fetch Requests?
When a component unmounts or re-fetches, the previous request may still be in flight. If it resolves after the new request, stale data overwrites fresh data. AbortController cancels in-flight requests cleanly.
AbortController Basics
Create an AbortController, pass its signal to fetch, and call controller.abort() to cancel. Fetch throws an AbortError when aborted.
const controller = new AbortController();
try {
const res = await fetch('/api/data', { signal: controller.signal });
const data = await res.json();
setData(data);
} catch (err) {
if (err instanceof DOMException && err.name === 'AbortError') {
console.log('Request was cancelled');
} else {
setError((err as Error).message);
}
}
// To cancel:
controller.abort();In useEffect Cleanup
Create an AbortController at the start of the effect and call abort() in the cleanup function. This automatically cancels the request when deps change or the component unmounts.
useEffect(() => {
const controller = new AbortController();
async function load() {
try {
const res = await fetch(`/api/user/${userId}`, { signal: controller.signal });
if (!res.ok) throw new Error(`${res.status}`);
setUser(await res.json());
} catch (err) {
if ((err as DOMException).name !== 'AbortError') {
setError((err as Error).message);
}
}
}
load();
return () => controller.abort();
}, [userId]);AbortError vs Network Error
An aborted request throws a DOMException with name 'AbortError'. Always check for it specifically and don't show it as a user-visible error — it's expected cleanup behaviour.
signal.aborted Property
Check controller.signal.aborted to test whether a signal has been aborted. Useful for checking before a setState call in async code.
const data = await fetchData();
if (!controller.signal.aborted) {
setData(data); // safe to update state
}Cancelling Multiple Requests
One AbortController can cancel multiple fetch requests by passing the same signal to all of them.
const controller = new AbortController();
const { signal } = controller;
await Promise.all([
fetch('/api/users', { signal }),
fetch('/api/products', { signal }),
fetch('/api/settings', { signal }),
]);
controller.abort(); // cancels all threeAbortController with Axios
Axios supports AbortController's signal through the signal option in config. The signal interface is the same as fetch.
const controller = new AbortController();
await axios.get('/api/data', { signal: controller.signal });
// In cleanup:
return () => controller.abort();React Query Handles This Automatically
When using TanStack Query (React Query), cancellation is handled for you. React Query creates and aborts controllers internally. This is one of the reasons to prefer it over manual fetch patterns.
Timeout with AbortController
Combine AbortController with setTimeout to implement request timeouts.
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5s timeout
try {
const data = await fetch(url, { signal: controller.signal });
// ...
} finally {
clearTimeout(timeoutId);
}AbortSignal.timeout() — Modern Shortcut
In modern browsers, AbortSignal.timeout(ms) creates a signal that automatically aborts after the specified duration without needing a manual controller.
const res = await fetch('/api/data', {
signal: AbortSignal.timeout(5000) // 5 second timeout
});Cleanup Is Critical in React 18 Strict Mode
React 18 Strict Mode mounts effects twice in development. Without AbortController cleanup, you'll see double fetches and potential state-on-unmounted-component warnings. The cleanup pattern prevents both.
Quick Check
How do you prevent a stale network response from updating state after a component re-renders?
Recap: AbortController
Create AbortController per effect. Pass signal to fetch/axios. Abort in cleanup function. Ignore AbortError — it's expected. Use signal.aborted before setState in async code. One controller can cancel many requests. AbortSignal.timeout() for timeouts. React Query handles all this automatically.
Frequently asked questions
Is the “AbortController for Cleanup” lesson free?
Yes — the full text of “AbortController for Cleanup” is free to read here on the web, and the Frontend Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Frontend Academy course, upgrade to CoddyKit PRO.
What will I learn in “AbortController for Cleanup”?
Create an AbortController, pass its signal to fetch, and cancel in-flight requests in the cleanup function to prevent state updates on unmounted components. You practise Frontend Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Frontend Academy?
No prior experience is required. Frontend Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “AbortController for Cleanup” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Frontend Academy lesson?
Yes. Every Frontend Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- useEffect Basics: Dependencies and Cleanup
- Fetching Data on Mount
- Handling Loading and Error States
- AbortController for Cleanup