Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Hooks setTimeout and clearTimeout

I read the 'Using the Effect Hook' doc but I'm still having a hard time cleaning up side effects from useEffect hook. Specifically I have this class component, and I'd like to learn how it can be converted to function component using useEffect hook.

class Alert extends PureComponent {
  componentDidMount() {
    this.handleSetTimeout()
  }

  componentDidUpdate() {
    this.handleClearTimeout()
    this.handleSetTimeout()
  }

  componentWillUnmount() {
    this.handleClearTimeout()
  }

  handleSetTimeout = () => {
    const { alert: { id, ttl }, handlePopAlert } = this.props
    if (!ttl) return
    this.timeout = setTimeout(() => handlePopAlert(id), ttl)
  }

  handleClearTimeout = () => {
    if (!this.timeout) return
    clearTimeout(this.timeout)
    this.timeout = null
  }

  render() { return (...) }
}
like image 996
cocacrave Avatar asked Feb 07 '19 15:02

cocacrave


People also ask

How do you use setTimeout and clearTimeout in React JS?

To clear a timeout or an interval in React with hooks: Use the useEffect hook to set up the timeout or interval. Return a function from the useEffect hook. Use the clearTimeout() or clearInterval() methods to remove the timeout when the component unmounts.

Is clearTimeout necessary?

Save this answer. Show activity on this post. clearTimeout is only necessary for cancelling a timeout. After the timeout fires, it can safely be left alone.

How do you call a function in setTimeout in React?

How to use setTimeout in React. The setTimeout function accepts two arguments: the first is the callback function that we want to execute, and the second specifies the timeout in milliseconds before the function will be called. setTimeout(() => console. log('Initial timeout!'


1 Answers

The function passed to useEffect may return a clean-up function.The clean-up function runs before the component is removed from the UI to prevent memory leaks. Additionally, if a component renders multiple times (as they typically do), the previous effect is cleaned up before executing the next effect.

In your case since the handlePopAlert function needs to be called based on the id passed from props, the effect needs to run whenever the id, ttl is changed for which you pass the second argument to useEffect as the id and ttl

const Alert = (props) => {
  const { alert: { id, ttl }, handlePopAlert } = this.props
  useEffect(() => {
    const timeout = setTimeout(() => {
       handlePopAlert(id)
    }, ttl)
    return () => {
       clearTimeout(timeout);
    }
  }, [id, ttl]);

  return (...)
}
like image 156
Shubham Khatri Avatar answered Sep 19 '22 00:09

Shubham Khatri