DEV Community

Discussion on: 6 use cases of the useEffect ReactJS hook

Collapse
dikamilo profile image
dikamilo

Fetching API data in useEffect is always tricky and you should always remember to cancel you subscription here. Your component may be unmounted when promise resolves and this will try to set state that will cause memory leaks. You will also see warning in console about this.

useEffect(() => {
    let mounted = true;

    const fetchData = async () => {
        const response = await fetch('https://swapi.dev/api/people/1/');
        const data = await response.json();

        if(mounted) {
            setBio(data);
        }
    };
    fetchData();

    return () => mounted = false;
}, []);
Enter fullscreen mode Exit fullscreen mode
Collapse
colocodes profile image
Damian Demasi Author

I didn't know about that, so thank you very much for pointing that out! I'll take this into account in future implementations of useEffect.

Collapse
digitalbrainjs profile image
Dmitriy Mozgovoy

Or we can use a bit of magic :) (Live Demo)

import { useAsyncEffect } from "use-async-effect2";
import cpAxios from "cp-axios";

function TestComponent({url}) {
  const [cancel, done, result, err] = useAsyncEffect(
    function* () {
      return (yield cpAxios(url)).data;
    },
    { states: true }
  );

  return (
    <div>
      {done ? (err ? err.toString() : JSON.stringify(result)) : "loading..."}
      <button className="btn btn-warning" onClick={cancel} disabled={done}>
        Cancel async effect (abort request)
      </button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode
Collapse
colocodes profile image
Damian Demasi Author

I definitely have to check Axios out!