DEV Community

King Elisha
King Elisha

Posted on

Correct way to handle API requests in a useEffect hook

It is common to issue an asynchronous request to an API in a useEffect hook. Perhaps to fetch some data which is eventually used to update component state. Something like this:

const [data, setData] = useState([]);

useEffect(() => {
  axios.get('get/some/data').then(({ data }) => {
    setData(data);
  });
}, []);
Enter fullscreen mode Exit fullscreen mode

It is also common to encounter a situation where the component unmounts before the request is complete. The callback will still be executed if the component unmounts because the request was not cancelled. Consequently, when setData is called, this interesting warning pops up in the browser console:

Warning: Can’t perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

How to fix this

To fix this, the request needs to be cancelled when the component unmounts (in the useEffect cleanup function). This can be easily achieved with axios as follows:

const [data, setData] = useState([]);

useEffect(() => {
  const cancelToken = axios.CancelToken.source();

  axios
    .get('get/some/data', { cancelToken: cancelToken.token })
    .then(({ data }) => {
      setData(data);
    })
    .catch((err) => {
      if (axios.isCancel(err)) {
        // TODO
      }
    });

  return () => {
    cancelToken.cancel();
  };
}, []);
Enter fullscreen mode Exit fullscreen mode

This can also be accomplished with fetch using AbortController as follows:

const [data, setData] = useState([]);

useEffect(() => {
  const controller = new AbortController();

  fetch('get/some/data', { signal: controller.signal })
    .then((res) => res.json())
    .then((data) => {
      setData(data);
    })
    .catch((err) => {
      if (err.name === 'AbortError') {
        // TODO
      }
    });

  return () => {
    controller.abort();
  };
}, []);
Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
naucode profile image
Al - Naucode

That was a nice read! Liked, bookmarked and followed, keep the good work!

Collapse
 
elishaking profile image
King Elisha

Thanks 🙏