0

Working on a countdown timer in React and not understanding how/where to place setTimeout function. It seems to work when I put it in the render before the return, but state properties aren't defined then so it starts counting from zero to negative numbers :/ I have tried doing something like:

 class App extends React.Component {
 constructor(props) {
    super(props)
    this.state = {
      start: '', //'10:10:10'
      end: '',
      startSec: '', //'36610'
      endSec: ''
    }
    this.clicked = this.clicked.bind(this);
    this.handleTimeout = this.handleTimeout.bind(this);
  }

  handleTimeout() {
    // decrement state.startSec
    //^thought this would trigger re-render every sec when  
    //called in clicked() 

  }

  clicked() {
    let re=/^([0-1]\d|2[0-3]):([0-5]\d):([0-5]\d)$/;
    let validStart = re.test(this.state.start);
    let validEnd = re.test(this.state.end);
    let start = this.state.start.split(":");
    let end = this.state.end.split(":");
    let startSec =  (Number(start[0]) * 3600) + (Number(start[1]) * 60) + (Number(start[2]));
    let endSec = (Number(end[0]) * 3600) + (Number(end[1]) * 60) + (Number(end[2]));


    // validate inputs
    if(!validStart || !validEnd) { alert('please use format HH:MM:SS') }     
    if(endSec > startSec) {
      alert('Please make end time less than start time!');
    }

    //where I am stuck
    this.setState({ startSec: startSec }); 

    if(this.state.startSec > this.state.endSec) {
      setInterval(this.handleTimeout() ,1000);
    }
  }

  render () {
    return (
      <div>
        <h2> Timer </h2>
        <div id="timer">
          Start Time <input type="text" placeholder="hh:mm:ss" onChange={(e) => {this.setState({start: e.target.value})}} /><br />
          End Time <input type="text" placeholder="hh:mm:ss" onChange={(e) => {this.setState({end: e.target.value})}}/> <br /><br />
          <button onClick={this.clicked}> Start Countdown </button><br /><br />
          <div id="output">{this.state.startSec}</div>
        </div>
      </div>
    );
  }
}

Updated https://jsfiddle.net/lydiademi/69z2wepo/91973/

I have referenced posts related to timers like Countdown timer in React

but wasn't able to connect to this problem,

thanks for any help..!

Lyddem
  • 45
  • 1
  • 6

1 Answers1

0

Well the reason its only calling it once is you need to pass the function into setInterval, you are instead calling the function and passing its return value (undefined).

So instead of

setInterval(this.handleTimeout() ,1000);

It should be

setInterval(this.handleTimeout ,1000);
  • you need to keep track of previously started Intervals so you can stop them before starting a new one

if(this.currentInterval) {
  clearInterval(this.currentInterval);
}
this.currentInterval = setInterval(this.handleTimeout, 1000);
Chris Phillips
  • 673
  • 5
  • 10