cocacrave
cocacrave

Reputation: 2633

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 (...) }
}

Upvotes: 7

Views: 12678

Answers (1)

Shubham Khatri
Shubham Khatri

Reputation: 281656

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 (...)
}

Upvotes: 12

Related Questions