David Scherer-ODell
David Scherer-ODell

Reputation: 21

My timer won't start and Im not sure why?

I am creating a timer function. For now, I just want the timer to start when the component loads, so I put the action in the componentWillMount. For some reason, the timer is not starting and i can't figure out why.

constructor(props) {
        super(props);
        this.state = {
            timerStarted: false,
            timerStopped: true,
            hours: 0,
            minutes: 0,
            seconds: 0,
            captures: []
        }
        //We store the Timer Started and Stoped bool also the cptures array for rendering it on the app.

        this.handleTimerStart = this.handleTimerStart.bind(this);
    }

    handleTimerStart(e) {
        e.preventDefault();
        alert('Timer Started!');
        if(this.state.timerStopped) {
            this.timer = setInterval(() => {
                this.setState({timerStarted: true, timerStopped: false});
                if(this.state.timerStarted) {
                    if(this.state.seconds >= 60) {
                        this.setState((prevState) => ({ minutes: prevState.minutes + 1, seconds: 0}));
                    }
                    if(this.state.minutes >= 60) {
                        this.setState((prevState) => ({ hours: prevState.hours + 1, minutes: 0, seconds: 0}));
                    }
                    this.setState((prevState) => ({ seconds: prevState.seconds + 1 }));
                }

            }, 1000);
        }
    }

    handleTimerStop() {
        this.setState({timerStarted: false, timerStopped: true});
        clearInterval(this.timer);
        /*this.handleTimerStop.bind(this); <--this is the stop action method*/
    }

    componentDidMount() {
        this.handleTimerStart;
    }

Upvotes: 0

Views: 35

Answers (2)

Ra&#250;l C. Rivero
Ra&#250;l C. Rivero

Reputation: 297

Here's an example of the Component that I use.

class Timer extends Component{
    constructor(...props) {
        super(...props)

        this.state = {
            seconds: 0,
            minutes: 0,
            hours: 0,
            timerStopped: true,
            inter: setInterval(this.timer, 1000)
        }
    }

    timer = event => {
        const {hours, minutes, seconds, timerStopped} = this.state;
        if(!timerStopped){
            seconds += 1;
            if(seconds >= 60){
                minutes += 1;
                seconds = 0;
            }
            if(minutes >= 60){
                hours += 1;
                minutes = 0;
            }
            this.setState({hours, minutes, seconds});
        }
    }
}

Upvotes: 0

larz
larz

Reputation: 5766

setState is asynchronous, so when you set timerStarted to true and then immediately check it, you aren't guaranteed to have the freshest state. A good solution is to use the second argument of setState, which is a callback that is fired after state is actually updated.

this.setState({timerStarted: true, timerStopped: false}, () => {
    if(this.state.timerStarted) {
    // do all of your things
    }
});

Upvotes: 1

Related Questions