javascript / intermediate
Snippet
Cancelling In-Flight Async Fetch Requests in React Effects via AbortController
When fetching data in a useEffect hook, rapid prop changes or unmounting can cause race conditions and memory leaks. By pairing standard Web API AbortController with the fetch signal option, in-flight HTTP requests are cleanly aborted in the effect's cleanup function, ignoring expected 'AbortError' exceptions.
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 { useState, useEffect } from 'react';function UserProfile({ userId }) {const [user, setUser] = useState(null);useEffect(() => {const controller = new AbortController();const { signal } = controller;async function loadUserData() {try {const res = await fetch(`/api/users/${userId}`, { signal });const data = await res.json();setUser(data);} catch (err) {if (err.name !== 'AbortError') {console.error('Fetch failed:', err);}}}loadUserData();return () => {controller.abort();};}, [userId]);return user ? <div>{user.name}</div> : <p>Loading...</p>;}
react
Breakdown
1
const controller = new AbortController();
Instantiates a new controller to generate a cancellation signal for async operations.
2
const res = await fetch(`/api/users/${userId}`, { signal });
Passes the controller's abort signal to fetch to link network request lifecycle with component lifecycle.
3
if (err.name !== 'AbortError') {
Differentiates intentional cancellations triggered by cleanup from actual network or parsing failures.
4
return () => { controller.abort(); };
Cleanup callback invoked by React when dependencies change or on unmount, aborting the pending request.