How to use setInterval in React

How to use setInterval in React
0

#1

I am working on the Pomodoro Clock Project and I am wondering how I can make the setInterval method to work in react.

I have a code something like this :


class Pomodoro extends React.Component{
    constructor(props){
        super(props) 
                this.state = {
                          count : 25
                            }
   this.handleStartStop = this.handleStartStop.bind(this);
}

 handleStartStop(){
       
    let counter = setInterval(timer , 1000)
         this.state.count *= 60;
            function timer() {
                this.setState({
               count: this.state.count -= 1   
                    })
            }
    }

 render(){
      return(
      <div>
          
           <div>
                    <p id="timer-label"> Session</p>
                    <p id="time-left">
                        {this.state.count}
                    </p>
            </div>
          
          <button id="start_stop" onClick={this.handleStartStop}>
                    Start/Stop
           </button>
      </div>
      )
 }

}

What I want to happen is , when I click the Start/Stop button . the {this.state.count} will decrement by 1 but I don’t know how to use setInterval while handling events.

Every comment and suggestions is appreciated.


#2

What is currently happening when you try to run your code? Is this your entire project so far? If not, can you post a link to your full project? It would make it easier for us to understand the direction you are taking with the project.

Also, in your handleStarStop method, you are mutating state directly two times instead of using setState. I move the timer function to the top of the function and properly indented your code to make it more readable.

  handleStartStop() {
    function timer() {
      this.setState({
        count: (this.state.count -= 1) // mutating state directly here
      });
    }

    let counter = setInterval(timer, 1000);
    this.state.count *= 60; // mutating state directly here
  }

Your logic is very confusing. Inside the timer function you are attempting to decrease this.count by one and after the setInterval function you are attempting to replace this.state.count by multiplying it by 60? What exactly are you trying to achieve in your handleStartStop method?


#3

React is JavaScript so setInterval works exactly the same because it is the same.

On issue I see at a quick glance is

this.state.count *= 60;

You should never set state directly ouside of the constructor but should use setState. And since state is dependant on the previous state, AFAIK you are supposed to use the callback as the first parameter, and not an object.


#4

@randelldawson , here is my full code as of now . I am using my own text editor so I will just paste it here:

import React from "react";
import ReactDOM from "react-dom";


//Break Label
function BreakLabel() {
        return <p id="break-label"> Break Length </p>
    }

//Session Label
function SessionLabel() {
    return <p id="session-label"> Session Length </p>
}

class Pomodoro extends React.Component{
    constructor(props){
        super(props) 
                this.state = {
                    break : 5,
                    session : 25,
                    count : 25,
                }
        this.handleClickBreakDecrement = this.handleClickBreakDecrement.bind(this);
        this.handleClickBreakIncrement = this.handleClickBreakIncrement.bind(this);
        this.handleClickSessionDecrement = this.handleClickSessionDecrement.bind(this);
        this.handleClickSessionIncrement = this.handleClickSessionIncrement.bind(this);
        this.handleStartStop = this.handleStartStop.bind(this);
    }
    
    handleClickBreakDecrement() {
        this.setState({
            break : this.state.break - 1
        })
    }
    
    handleClickSessionDecrement() {
        this.setState({
            session : this.state.session - 1 ,
            count : this.state.count - 1
        })
    }
    
    handleClickBreakIncrement() {
        this.setState({
            break: this.state.break +1
        })
    }
    
     handleClickSessionIncrement() {
        this.setState({
            session : this.state.session + 1 ,
            count : this.state.count + 1
        })
    }
    
    handleStartStop() {
    this.timer = setInterval(() => this.setState(prevState => 
        if (prevState.count === 0) return null;

        return {
            count: prevState.count - 1,
        };
    ), 1000);
}
    
    handleReset(){
        
    }
    render(){
        
        let count; 
        
        if(this.state.count % 60 >= 10) {
            count = Math.floor(this.state.count /60)+":"+this.state.count%60
          }
        
        
        return (
                <div>
            
              {/* Break Label */}
        <div className="breakContainer">
                <BreakLabel />
            <div className="breakButton">
                <button id="break-decrement" onClick={this.handleClickBreakDecrement}>
                    handleClickBreakDecrement
                </button>
                <p id="break-length"> {this.state.break} </p>
                <button id="break-increment" onClick={this.handleClickBreakIncrement}>           handleClickBreakIncrement
                </button>
            </div> 
        </div> 
                
                {/* Session Label */}
        <div className="sessionContainer">
                <SessionLabel />
            <div className="sessionButton">
                <button id="session-decrement" onClick={this.handleClickSessionDecrement}>
                    handleClickSessionDecrement
                </button>
                <p id="session-length"> {this.state.session} </p>
                <button id="session-increment" onClick={this.handleClickSessionIncrement}>
                    handleClickSessionIncrement
                </button>
            </div>
        </div>
                
                {/* Timer Label */}
                <div>
                    <p id="timer-label"> Session</p>
                    <p id="time-left">
                    {count}
                    </p>
                </div>
                
                {/* Start, Stop and Reset Button*/}
                <div>
                <button id="start_stop" onClick={this.handleStartStop}>
                    Start/Stop
                </button>
                
                <button id="reset" onClick={this.handleReset}>
                    Reset
                </button>
                </div>
                
            </div>
        )
    } 
}



   ReactDOM.render(
        <Pomodoro />,
        document.getElementById('app')
        );
        
       
 

Sorry for mutating state directly, I have also read just now in the https://reactjs.org/tutorial/tutorial.html “never mutate state directly,” But as of now, I want to focus on handleStartStop() . Thank you