javascript / intermediate
Snippet
Cancelling Pending Fetch Requests on Component Unmount with AbortController
When components unmount or dependency props change before an asynchronous fetch resolves, continuing to update state can cause race conditions. Using JavaScript's native AbortController allows passing a signal to fetch, which can be triggered in the useEffect cleanup return function. Checking err.name !== 'AbortError' prevents recording intentional aborts as component errors.
snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import React, { useState, useEffect } from 'react';export function UserProfile({ userId }) {const [user, setUser] = useState(null);const [error, setError] = useState(null);useEffect(() => {const controller = new AbortController();async function loadData() {try {const res = await fetch(`/api/users/${userId}`, { signal: controller.signal });if (!res.ok) throw new Error(`HTTP error: ${res.status}`);const data = await res.json();setUser(data);} catch (err) {if (err.name !== 'AbortError') {setError(err.message);}}}loadData();return () => controller.abort();}, [userId]);if (error) return <p role="alert">Error: {error}</p>;if (!user) return <p>Loading...</p>;return <h1>{user.name}</h1>;}
react
Breakdown
1
const controller = new AbortController();
Instantiates a new controller to generate a cancellation signal for web requests.
2
const res = await fetch(`/api/users/${userId}`, { signal: controller.signal });
Attaches the abort signal directly to the fetch configuration options.
3
if (err.name !== 'AbortError') {
Filters out DOMException abort errors so that component unmounts do not display false error UI.
4
return () => controller.abort();
Runs on dependency change or unmount to immediately cancel the in-flight network request.