While using a React app, we might encounter a situation where we want to abort an ongoing network request (e.g., a fetch or post request) when we navigate away from a React component. By doing this, we prevent unnecessary data fetching and potential memory leaks.
The objective described above is achieved by using the AbortController
API within a basic React app. The steps to perform this are explained below.
If we haven’t already set up a React app on our system, we can create one using the following commands in the terminal one after the other. Learn how to create a simple React app.
npx create-react-app <name-of-directory>
cd <name-of-directory>
Note: In place of the
<name-of-directory>
tag, we can write a directory name of our choice.
AbortController
API We’ll assume that a component named MyComponent
that is used to make network requests is already present in our application. Let’s use a simple example that guides us on how to set up the component to use the AbortController
API.
// Import the necessary functions and modules from the 'react' library.import React, { useState, useEffect } from 'react';const MyComponent = () => {// Initialize a piece of state called 'data' using the 'useState' hook and set it to null.const [data, setData] = useState(null);// Set up a side effect using the 'useEffect' hook.useEffect(() => {// Create a new AbortController instance to allow aborting the fetch request.const abortController = new AbortController();// Get the signal from the AbortController.const signal = abortController.signal;//Fetch request to 'https://api.example.com/data' with the signal is being performedfetch('https://api.example.com/data', { signal }).then(response => response.json()).then(resultData => {// Checking if the signal has not been aborted.if (!signal.aborted) {// Update the 'data' state with the fetched data.setData(resultData);}}).catch(error => {// Handling any errors from the fetch.if (!signal.aborted) {console.error('Request failed:', error);}});// Defining a cleanup function that will run when the component unmounts.return () => {// Abort the fetch request when the component unmounts.abortController.abort();// Log a message indicating that the request has been aborted.console.log('Request has been aborted successfully.');};}, []); // The empty dependency array means this effect runs once after initial render.return (// Render either the data or a loading message based on the 'data' state.<div>{data ? (<div>Data: {JSON.stringify(data)}</div>) : (<div>Loading data...</div>)}</div>);};export default MyComponent;
In the code above, we are using the AbortController()
object and its associated signal
to abort the ongoing request when the component is unmounted or cleaned up. We are requesting data from a dummy API with the URL https://api.example.com/data
.
Note: Other API URLs can be used here, such as
https://jsonplaceholder.typicode.com/posts
.
Next, we will integrate the component made in step 2 into the App.js
file (present in the /src
directory) of our React app by writing the following code.
import React from 'react';import MyComponent from './MyComponent';function App() {return (<div className="App"><MyComponent /></div>);}export default App;
After performing steps 1 to 4, we finally run the React app to start the server using the command shown below.
npm start
Here, we can see the expected output of the steps performed above by running the application down below.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#000000" /> <meta name="description" content="Web site created using create-react-app" /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> <!-- manifest.json provides metadata used when your web app is installed on a user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ --> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <!-- Notice the use of %PUBLIC_URL% in the tags above. It will be replaced with the URL of the `public` folder during the build. Only files inside the `public` folder can be referenced from the HTML. Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> <title>React App</title> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div> <!-- This HTML file is a template. If you open it directly in the browser, you will see an empty page. You can add webfonts, meta tags, or analytics to this file. The build step will place the bundled scripts into the <body> tag. To begin the development, run `npm start` or `yarn start`. To create a production bundle, use `npm run build` or `yarn build`. --> </body> </html>
To see a difference in the output of the webpage, try changing the API URL in the MyComponent.js
file in the /src
directory to any working API URL that takes time to respond. We can pick any URL, but for this example, we will use the https://jsonplaceholder.typicode.com/posts?_delay=5000
URL.
Note: In the URL
https://jsonplaceholder.typicode.com/posts?_delay=5000
, the_delay=5000
parameter introduces a delay of five seconds before the API responds. Adding a delay can be handy in testing the abort request feature.
An important thing to know is that there are two scenarios of running this application. The first scenario is that, after going into the console section of the webpage (by right clicking the “F12” key and selecting the “Inspect” option), we will be able to see the printed error message Request failed: Failed to fetch at...
as shown below. This is because the network request from the API failed to go through and subsequently, the request was aborted via the abortController.abort()
method.
Note: The
Request failed: Failed to fetch error at...
error message will list various file names, depending on the complexity of our application.
The second scenario is that if we use the API URL https://jsonplaceholder.typicode.com/posts?_delay=5000
, we will see that after five seconds, some data will be fetched from the API and displayed on the webpage without the error message in the first instance.
In both of these scenarios, we will see the message Request has been aborted successfully
printed in the console.
To reiterate, incorporating this method in aborting network requests when navigating away can prevent unnecessary data fetching and potential leaks. This leads to a smoother and more efficient user experience, better resource management, and improved code quality in our React applications.
Free Resources