Using AbortController with Fetch API and ReactJS
AbortController is a JavaScript interface that allows you to cancel one or more DOM requests (like Fetch API calls) as and when needed. It provides a way to abort fetch requests.
Why Abort Requests? 🚫
Imagine you’re building a search feature for an e-commerce app. Every time a user types a letter (like “w”, then “wi”, then “wir”…), your app sends a new Fetch request. If the user types fast, older requests might resolve after newer ones, causing outdated results to flicker on the screen. Worse, if they leave the page mid-fetch, React might try to update a component that’s already gone, leading to errors.
By using AbortController, you can cancel pending Fetch requests, ensuring that your application remains efficient.
How to Use AbortController with Fetch API
Now, let’s see how to use AbortController with React .
Step 1: Create an AbortController
const controller = new AbortController();
const signal = controller.signal;The signal property is an AbortSignal object that can be passed to the Fetch API to associate it with the controller.
Step 2: Pass the Signal to Fetch
Next, you pass the signal to the fetch function as part of the options object.
fetch('https://api.example.com/data', { signal })
.then(response => response.json())
.then(data => console.log(data))
.catch(error => {
if (error.name === 'AbortError') {
console.log('Fetch aborted');
} else {
console.error('Fetch error:', error);
}
});Step 3: Abort the Fetch Request
controller.abort();To abort the fetch request, you call the abort method on the AbortController instance.
Using AbortController in ReactJS
Let’s create a React component for searching products. We’ll use AbortController to cancel outdated searches.
import React, { useState, useEffect } from 'react';
function ProductSearch() {
const [query, setQuery] = useState(''); // Search input, like "wireless headphones"
const [results, setResults] = useState([]); // Search results
const [loading, setLoading] = useState(false);
useEffect(() => {
// Step 1: Create the AbortController
const controller = new AbortController();
const { signal } = controller;
const fetchResults = async () => {
if (!query) return; // Don't search for empty queries
setLoading(true);
try {
// Step 2: Pass the signal to Fetch
const response = await fetch(
`https://api.example.com/products?search=${query}`,
{ signal }
);
const data = await response.json();
setResults(data);
} catch (err) {
// Step 3: Handle cancellation gracefully
if (err.name === 'AbortError') {
console.log('Request aborted! Moving on...');
} else {
console.error('Oops!', err);
}
} finally {
setLoading(false);
}
};
fetchResults();
// Step 4: Abort if the query changes or the component unmounts
return () => controller.abort();
}, [query]); // Re-run effect when `query` changes
return (
<div>
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search for products..."
/>
{loading && <p>Searching for "{query}"...</p>}
<ul>
{results.map((product) => (
<li key={product.id}>{product.name}</li>
))}
</ul>
</div>
);
}
export default ProductSearch;Breaking It Down 🔍
- The
useEffectHook: Whenever the user types (updatingquery), this effect runs. Each new search creates a freshAbortController. - The Cleanup Function: When the effect re-runs (because
querychanged) or the component unmounts, React callscontroller.abort(). This cancels the previous Fetch request if it’s still pending. - Handling Errors: If a request is aborted, Fetch throws an
AbortError. We ignore it because it’s intentional. Real errors (like network failures) are logged for debugging.
Pro Tips 💡
- Avoid Memory Leaks: Always abort requests when a component unmounts. React’s cleanup function in
useEffectis perfect for this. - Debounce for Extra Smoothness: Combine AbortController with a debounce function (like a 300ms delay) to avoid spamming the API on every keystroke.
- Not Just for Search: Use AbortController for any Fetch call that might become irrelevant — like canceling a file upload when the user closes a modal.
Conclusion
Using AbortController with the Fetch API in ReactJS is a powerful way to manage and cancel fetch requests. It helps in making your application more efficient and responsive by avoiding unnecessary network requests and potential memory leaks.
Happy coding!
