Home > Net >  How to asynchronous tasks in a useEffect cleanup function?
How to asynchronous tasks in a useEffect cleanup function?

Time:09-21

I am getting this error:

index.js:1 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. index.js:1 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. at Products (http://localhost:3000/static/js/main.chunk.js:2779:5) at div at Home at RenderedRoute (http://localhost:3000/static/js/vendors~main.chunk.js:246119:5) at Routes (http://localhost:3000/static/js/vendors~main.chunk.js:246568:5) at Router (http://localhost:3000/static/js/vendors~main.chunk.js:246499:15) at BrowserRouter (http://localhost:3000/static/js/vendors~main.chunk.js:244709:5) at div at App

I assume the problem is here:

Products.js

const [products, setProducts] = useState([]);

useEffect(() => {
    const getProdcuts = async () => {
      try {
        const res = await axios.get(
          category
            ? `http://localhost:5000/e-mart/products?category=${category}`
            : `http://localhost:5000/e-mart/products`
        );
        setProducts(res.data);
      } catch (err) {
        console.log(err.message);
      }
    };
    getProdcuts();
  }, [category]);

My home page is not loading. No problem is shown in the terminal. How can I resolve this?

CodePudding user response:

You can use the AbortController to abort an async request, it'd look like

useEffect(() => {
    const abortController = new AbortController();
    const getProdcuts = async () => {
      try {
        const res = await axios.get(
          category
            ? `http://localhost:5000/e-mart/products?category=${category}`
            : `http://localhost:5000/e-mart/products`,
          { signal: abortController .signal } // Notice this line here
        );
        setProducts(res.data);
      } catch (err) {
        console.log(err.message);
      }
    };
    getProdcuts();

    return () => {
      // Function returned from useEffect is called on unmount
      // Here it'll abort the fetch
      abortController.abort(); 
    }

  }, [category]);

That's a quick way to fix this problem but if you're not sure why this problem is happening in the first place it's probably because you're not expecting Products to unmount. You might have a parent component rendering Products or one of its parents conditionnally and a state change cause an unmount before fetch is done.

CodePudding user response:

This error has the answer itself.

To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function. at Products

Cleanup function in useEffect can be achieved by returning the async function.

You can try this -

useEffect(() => {
return async () => {
  try {
    const res = await axios.get(
      category
        ? `http://localhost:5000/e-mart/products?category=${category}`
        : `http://localhost:5000/e-mart/products`
    );
    setProducts(res.data);
  } catch (err) {
    console.log(err.message);
  }
};
}, [category]);

and secondly, you can just try passing the dependency array as empty.

  • Related