How To Cancel Fetch Requests In React.js

Performing asynchronous operations, such as fetching data from an API, is a common task in React.js applications.

However, situations may arise where you need to cancel a fetch request, especially if the component unmounts or the user initiates another action. So therefore let’s see how to cancel fetch requests in React.js with code example:

Cancel Fetch or Ajax Requests In React.js

AbortController API to Cancel Fetch Request in React.js:

The AbortController is a built-in web API that allows you to cancel asynchronous operations, including fetch requests.

It works by creating an instance of AbortController and associating it with the fetch request. When cancellation is needed, you can call the abort method on the controller.

Here’s how you can implement it in a React component:

useEffect(() => {
    // Create an instance of AbortController to handle aborting fetch requests
    const controller = new AbortController();
    const signal = controller.signal;

    // Asynchronous function to fetch data from the API
    (async () => {
        try {
            // Fetch data from the API using fetch() with the provided signal
            const response = await fetch(apiURL, {
                signal,
            });
            // Parse the JSON response
            const result = await response.json();
            // Update the state with the fetched data
            setData(result);
        } catch (error) {
            // Handle errors, including aborted fetch requests
            if (error.name === "AbortError") {
                // Log a message if the fetch request was canceled due to component unmount
                console.log("Fetch request was canceled.");
            } else {
                // Log the error if there was an error fetching the data
                console.error("Error fetching data:", error);
            }
        }
    })();

    // Cleanup function to abort the fetch request when the component unmounts
    return () => controller.abort();
}, []); // Empty dependency array means this effect runs only once on mount

Example:

import { useEffect, useState } from "react";

const MyComponent = () => {
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(true);
    const apiURL = "https://jsonplaceholder.typicode.com/users";

    useEffect(() => {
        // Create an instance of AbortController
        const controller = new AbortController();
        const signal = controller.signal;

        const fetchData = async () => {
            try {
                const response = await fetch(apiURL, {
                    signal,
                });
                const result = await response.json();
                setData(result);
            } catch (error) {
                if (error.name === "AbortError") {
                    console.log("Fetch request was canceled.");
                } else {
                    console.error("Error fetching data:", error);
                }
            } finally {
                // Set loading to false, regardless of success or failure
                setLoading(false);
            }
        };

        fetchData();

        // Cleanup function to abort the fetch request when the component unmounts
        return () => controller.abort();
    }, []); // Empty dependency array

    return (
        <div>
            {loading ? <p>Loading...</p> : <p>Data: {JSON.stringify(data)}</p>}
        </div>
    );
};

export default MyComponent;

In this code:

  1. An instance of AbortController is created, and its signal is passed as an option to the fetch request.
  2. The useEffect hook sets up the fetch operation and the cleanup function to abort the request when the component unmounts.
  3. The AbortError is caught and handled separately from other errors.