Home > OS >  Clear Timeout set in click event in React
Clear Timeout set in click event in React

Time:11-24

I'm wondering how to clear a timeout, which is set in an onclick event in React. I'm aware you can easily cancel timeouts, when they are set in 'useEffect', but how about this use case?

export default function SomeComponent() {
    const onClick = () => {
        setTimeout(() => {
            // dome some logic like API calls,
            // which should be terminated, in case the component
            // is unmounted
        }, 2_500)
    }

  return (
    <div><button onClick={onClick}>Click me!</button></div>
  )
}

CodePudding user response:

Setting up your timeout in a manner similar to this example from MDM Web Docs is likely the solution you're after. In this case, you can add a useEffect to clear on component unmount.


/* Code taken from MDN Docs */
const alarm = {
  remind(aMessage) {
    alert(aMessage);
    this.timeoutID = undefined;
  },

  setup() {
    if (typeof this.timeoutID === 'number') {
      this.cancel();
    }

    this.timeoutID = setTimeout((msg) => {
      this.remind(msg);
    }, 1000, 'Wake up!');
  },

  cancel() {
    clearTimeout(this.timeoutID);
  }
};

/* Clear timeout on component unmount */
useEffect(() => {
  return () => {
    alarm.cancel()
  }
}, [alarm])

CodePudding user response:

Well you can save the timeout to a state and then clear it in the useEffect like this:

export default function SomeComponent() {
    const [timeoutInstance, setTimeoutInstance] = useState(null);
    const onClick = () => {
        const timeout = setTimeout(() => {
            // dome some logic like API calls,
            // which should be terminated, in case the component
            // is unmounted
        }, 2_500);
        setTimeoutInstance(timeout);
    }

    useEffect(() => {
      return () => {
        if(timeoutInstance) {
          clearTimeout(timeoutInstance);
          setTimeoutInstance(null);
        }
      }
    }, []);

    return (
      <div><button onClick={onClick}>Click me!</button></div>
    )
}
  • Related