Search code examples
reactjsasynchronoususe-effect

Asynchronous handling in useEffect


I'm using a custom hook to create a behaviour of auto signOut after 3 seconds. I'm calling this hook from my main component and deciding the state of login using isLogin. After setting the credentials, setLogin function is invoked and due to useEffect setTimeout gets loaded into memory. The problem is, after 3 seconds I'm getting this error,

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

If you think that this is not the correct way of handling such a type of scenario then please guide me.

const [isLogin, setLogin] = useState(someValue);

 useEffect(() => {
    if (tokenExist && notExpireYet) {
      setTimeout(() => remValue(), 3000);
    }
  }, [isLogin]);
        

Solution

  • The problem is your setTimeout call is called even after the component was unloaded. In order to clean up the effect properly between dependency changes, you should return a function that cleans up.

    In your case, it would be something like this:

    const [isLogin, setLogin] = useState(someValue);
    
    useEffect(() => {
      if (tokenExist && notExpireYet) {
        const id = setTimeout(() => remValue(), 3000);
        return () => clearTimeout(id);
      }
      
    }, [isLogin]);
    

    This will make sure your effect doesn't run when the component is no longer there.