Forgive me if this seems overly simple...this is the first thing I have ever made in React so I'm just trying to wrap my head around things. I'm already realizing I should have smaller component like buttons and render them with props and all that (goal is to refactor later!) but currently I am having a hard time figuring out how to use the setInterval method to change the state, and then stop that.
I'm building a pomodoro timer, and the general idea is that my state is maintaining the total seconds that the timer should have left. I have another function that will convert the total seconds into a time format I want to display.
My struggle is within my startStop() method, I would like the change the state of the running (the timer is running) to t/f and that will work, but I am clearly doing something wring with the setInterval. I want to set an interval (when there is time remaining) to change the state every second to be 1 second less. When I click the button again, the interval timer would stop and the current "state" of seconds remaining would be the same, so if you clicked the button again it would just start the timer again.
Thanks for the help! (This is all getting rendered from the create-react-app so there is more at my github is needed: https://github.com/ryanmdoyle/web-pomodoro)
import React, { Component } from "react ";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
sessionTimeEntry: 25, //in min
breakTimeEntry: 5, //in min
sessionRemainingSeconds: 1500, //in seconds
breakRemainingSeconds: 300, //in seconds
running: false,
timerLabel: "Session"
}
this.addSession = this.addSession.bind(this);
this.subSession = this.subSession.bind(this);
this.addBreak = this.addBreak.bind(this);
this.subBreak = this.subBreak.bind(this);
this.startStop = this.startStop.bind(this);
this.resetTimer = this.resetTimer.bind(this);
this.formatMinutes = this.formatMinutes.bind(this);
}
addSession() { //adding and subtracting methods need to also chage the session remaining in seconds to mirrow the entry time if ever changed
this.setState({
sessionTimeEntry: this.state.sessionTimeEntry + 1,
sessionRemainingSeconds: this.state.sessionRemainingSeconds + 60
})
}
subSession() {
this.setState({
sessionTimeEntry: this.state.sessionTimeEntry - 1,
sessionRemainingSeconds: this.state.sessionRemainingSeconds - 60
})
}
addBreak() {
this.setState({
breakTimeEntry: this.state.breakTimeEntry + 1,
breakRemainingSeconds: this.state.breakRemainingSeconds + 60
})
}
subBreak() {
this.setState({
breakTimeEntry: this.state.breakTimeEntry - 1,
breakRemainingSeconds: this.state.breakRemainingSeconds - 60
})
}
startStop() {
let timer;
const status = this.state.running;
switch (status) {
case false:
console.log("should start!")
this.setState({
running: true
})
while (this.state.breakRemainingSeconds > 0) {
timer = setInterval(() => {
this.setState({
breakRemainingSeconds: this.state.breakRemainingSeconds - 1
});
console.log(this.state.breakRemainingSeconds);
}, 1000)
}
break;
case true:
console.log("should stop")
this.setState({
running: false
})
clearInterval(timer)
break;
default:
break;
}
}
resetTimer() {
this.setState({
sessionTimeEntry: 25,
breakTimeEntry: 5,
sessionRemainingSeconds: 1500,
breakRemainingSeconds: 300,
running: false,
timerLabel: "Session"
})
}
formatMinutes(time) {
let seconds = time;
const minutes = (seconds % 60 === 0) ? ((seconds / 60) < 10 ? "0" + seconds / 60 : seconds / 60) : (Math.floor(seconds / 60) < 10 ? "0" + Math.floor(seconds / 60) : Math.floor(seconds / 60));
seconds = (seconds % 60 === 0) ? "00" : ((seconds % 60 < 10) ? "0" + (seconds % 60) : seconds % 60)
console.log(minutes + ":" + seconds);
return minutes + ":" + seconds;
}
render() {
return ( <
div >
<
h1 > Pomodoro Clock < /h1> <
h2 > {
this.state.sessionTimeEntry
} < /h2> <
div id = 'timerContainer' >
<
h3 id = "session-label" > Session Time < /h3> <
h3 id = "session-length" > {
this.formatMinutes(this.state.sessionRemainingSeconds)
} < /h3> <
button onClick = {
this.addSession
}
id = "session-increment" > ^ < /button> <
button onClick = {
this.subSession
}
id = "session-decrement" > v < /button> <
/div> <
div id = 'timerContainer' >
<
h3 id = "break-label" > Break Time < /h3> <
h3 id = "break-length" > {
this.state.breakTimeEntry
} < /h3> <
button onClick = {
this.addBreak
}
id = "break-increment" > ^ < /button> <
button onClick = {
this.subBreak
}
id = "break-decrement" > v < /button> <
/div> <
div >
<
button onClick = {
this.startStop
}
id = "start-stop" > Start / Stop < /button> <
button onClick = {
this.resetTimer
}
id = "reset" > Reset < /button> <
/div> <
/div>
)
}
}
export default App;
**************** UPDATE *****************
Figured it all out! Here is a link to the working codepen to see it in action.