10

On each question component, I am trying to clear the time out. So on componentWillMount() I will start the timer and then on componentDidUpdate() I will clear the timeout. The timer does not seem to be working.After the timer expires I will push the user back to the home page. Any idea why the using clearTimeout() isnt working?

class Questions extends Component { 
    constructor(props){
        super(props);
        this.state ={
            error: false,
            position: null,
            redirect: false
        } 
        this.error = this.error.bind(this);   
        this.errorFalse = this.errorFalse.bind(this); 
        this.timer = this.timer.bind(this); 
    }
    timer=()=>{
        setTimeout(() => { 
            console.log('this ran') 
            this.setState({
                redirect: true
            })

    }, 5000)
    }
    componentWillMount(){
        this.setState({
            error: false
        })
        this.timer();

    }
    componentDidUpdate(prevProps, prevState, snapshot, timer){
        console.log('updated')
        clearTimeout(this.timer);
    }
jdip88
  • 407
  • 1
  • 8
  • 22
  • Possible duplicate of [setTimeout / clearTimeout problems](https://stackoverflow.com/questions/3015319/settimeout-cleartimeout-problems) – Herohtar Apr 11 '18 at 20:29

2 Answers2

16

When you use setTimeout() it returns a timeoutID, which you use to clear the timeout.

To use it in your component, you need to store the timeoutID that was returned from the timer method:

class Questions extends Component {
  constructor(props) {
    super(props)
    this.state = {
      error: false,
      position: null,
      redirect: false
    }
    this.error = this.error.bind(this);
    this.errorFalse = this.errorFalse.bind(this);
    // this.timer = this.timer.bind(this); // don't bind an arrow function
  }
  timer = () => setTimeout(() => { // return the timeoutID
    console.log('this ran')
    this.setState({
      redirect: true
    })

  }, 5000);
  componentWillMount() {
    this.setState({
      error: false
    })
    this.timeoutID = this.timer(); // cache the timeoutID
  }
  componentDidUpdate(prevProps, prevState, snapshot, timer) {
    console.log('updated')
    clearTimeout(this.timeoutID); // clear the timeoutID
  }
Ori Drori
  • 166,183
  • 27
  • 198
  • 186
14

React Hooks

useEffect(() => {
    const timer = () => setTimeout(() => ...some work ... , 2000);
    const timerId = timer();
    return () => {
      clearTimeout(timerId);
    };
  });
Milan Vukovic
  • 141
  • 1
  • 3
  • 4
    Why did you wrap the `setTimeout` in a function, and called it? The function seems to return the value of the `setTimeout` anyway, so why didn't you just call the `setTimeout` and store its value as `timerId`? – Norbert Biró Sep 16 '21 at 11:10