0

Warning: Can't perform React state update on the unmounted component

App.js

App.js

App.js

After using the useIsMount approach, i am unable to pass the state value as props

  • Duplicate of [this question](https://stackoverflow.com/questions/59780268/cleanup-memory-leaks-on-an-unmounted-component-in-react-hooks/59956926#59956926) – HMR Jun 28 '20 at 07:52
  • @HMR, i tried with your approach. I am getting an empty array if I am trying to pass the props to another component. – Murugesh Aravind Jun 28 '20 at 08:12

1 Answers1

2

This happens when you try to set state on a component that has already unmounted. This is commonly seen in async operations where you make an async request, and then you try to set state once it resolves.

The process goes like this:

  1. Component mounts
  2. useEffect runs and fires the async request
  3. The async function creates a closure around the set state function
  4. The component unmounts (due to a change in UI for whatever reason)
  5. The request resolves
  6. The closured set state function is called - but the component that contains the state has already unmounted! Error happens here.

To fix this, you need to check to see if the component is still mounted before you call the state update function.

You can check to see if a component is mounted by using something like a useIsMounted hook. There are many examples of this hook online.

HMR commented with a link to a good useIsMounted hook, which I'l post here:

import { useRef, useEffect } from 'react';

const useIsMounted = () => {
  const isMounted = useRef(false);
  useEffect(() => {
    isMounted.current = true;
    return () => isMounted.current = false;
  }, []);
  return isMounted;
};

export default useIsMounted;

To use the hook, you call it in your component:

const isMounted = useIsMounted()

And inside your async function, check to see if the component is mounted before setting state:

if(isMounted.current) {
  // it's okay to set state here
}

Make sure you add the isMounted variable as a dependency of your useEffect so you have the most up to date value!

JMadelaine
  • 2,859
  • 1
  • 12
  • 17
  • 1
    sure, thanks for responding!. I will check on this. – Murugesh Aravind Jun 28 '20 at 07:46
  • 1
    @MurugeshAravind [This](https://github.com/jmlweb/isMounted/blob/master/index.js) is a good one. – HMR Jun 28 '20 at 07:47
  • @HMR, i tried the state effects on the isMounted.current but when i try to pass the props, it is going as an empty array – Murugesh Aravind Jun 28 '20 at 08:10
  • You're checking `isMounted.current` in the wrong place. You need to check it just before you set the state after the async request has resolved. Don't just check it in the function body, because it will always be true, since the function body is only run while the component is mounted (during the render cycle). – JMadelaine Jun 28 '20 at 10:35
  • Are you making async requests? Is that what your store does? If so, you'll need to await them. – JMadelaine Jun 28 '20 at 10:39