I do API call on component mount using useEffect and depend of response do some state changes, but what if my component destroys while request is in pending status, how can I undo this request and all functions that try to change my state on success
So using fetch you can do like this as shown below, you can user native abort in js
you can read more on here
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Route, Switch, Link } from "react-router-dom";
import "./styles.css";
const Home = () => {
const [data, setData] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [errorMessage, setErrorMessage] = useState(null);
useEffect(() => {
const abortController = new AbortController();
const getData = async () => {
try {
setIsLoading(true);
const response = await fetch(
"https://jsonplaceholder.typicode.com/comments",
{
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
signal: abortController.signal
}
);
if (response.ok) {
const body = await response.json();
setData(body);
setIsLoading(false);
return;
}
const customError = {
message: "Some Error Occured"
};
throw customError;
} catch (error) {
console.log(error.name);
setIsLoading(false);
if (error.name === "AbortError") {
setErrorMessage("Request has aborted");
return;
}
setErrorMessage("Internal server error");
}
};
getData();
return () => {
abortController.abort();
};
}, []);
return (
<>
{isLoading && <span>Loading Data, Please wait...</span>}
{errorMessage && <span>{errorMessage}</span>}
{data.length > 0
? data.map(d => {
return <p key={d.id}>{d.name}</p>;
})
: null}
</>
);
};
const Products = () => <>Products</>;
function App() {
return (
<BrowserRouter>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/products">Products</Link>
</li>
</ul>
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/products" component={Products} />
</Switch>
</BrowserRouter>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Working codesandbox
Note: You need to open the dev tools and make the network tab throttling to slow 3g from online and open the console so when clicking on the products link the api will get cancelled.
I hope this will give a better view of this problem
happy coding :)