I'm building a simple timer app. When the user clicks play the handlePlayPause
function is called. I've created an isRunning
boolean to check if the timer is already running. If it's not, the timer will start (this first part works), whilst if it is, the pauseTimer
function is called. This last function switches isRunning
back to false and should clear the interval. However, the interval does not get cleared. Can you see what i'm doing wrong?
Thank you for your help!
export default function App() {
const [sessionLength, setSessionLength] = useState(25)
const [breakLength, setBreakLength] = useState(5)
const [timeLeft, setTimeLeft] = useState(25 * 60 * 1000)
const [isRunning, setIsRunning] = useState(false)
let intervalId = null
let handlePlayPause = () => {
if (!isRunning) {
setTimeLeft(sessionLength * 60 * 1000)
playTimer()
} else if (isRunning) {
pauseTimer()
}
}
let playTimer = () => {
setIsRunning(true)
intervalId = setInterval(() => {
setTimeLeft(timeLeft => timeLeft - 1000)
parseToMinuteSeconds(timeLeft)
}, 1000)
}
let pauseTimer = () => {
setIsRunning(false)
clearInterval(intervalId)
}
let resetAll = () => {
setSessionLength(25)
setBreakLength(5)
}
let parseToMinuteSeconds = timeInMilliseconds => {
return //a string with the time in this format 00:00
}
return (
<div className="App">
<Background>
<UpperMetalBand />
<UpperPart />
<LowerPart />
<LowerMetalBand />
<Wrapper>
<Title>Pomodoro</Title>
<Subtitle>TIMER</Subtitle>
<PlayButton
id="start_stop"
onClick = {handlePlayPause}
>
<i className="fa fa-play" />
</PlayButton>
<Reload
onClick={resetAll}
id="reset"
>
<i className="fas fa-sync-alt" />
</Reload>
<Session
setSessionLength={setSessionLength}
sessionLength={sessionLength}
/>
<Break
setBreakLength={setBreakLength}
breakLength={breakLength}
/>
<span id="time-label">
<Timer id="time-left">00:00</Timer>
</span>
</Wrapper>
</Background>
</div>
)
}
I'm building a simple timer app. When the user clicks play the handlePlayPause
function is called. I've created an isRunning
boolean to check if the timer is already running. If it's not, the timer will start (this first part works), whilst if it is, the pauseTimer
function is called. This last function switches isRunning
back to false and should clear the interval. However, the interval does not get cleared. Can you see what i'm doing wrong?
Thank you for your help!
export default function App() {
const [sessionLength, setSessionLength] = useState(25)
const [breakLength, setBreakLength] = useState(5)
const [timeLeft, setTimeLeft] = useState(25 * 60 * 1000)
const [isRunning, setIsRunning] = useState(false)
let intervalId = null
let handlePlayPause = () => {
if (!isRunning) {
setTimeLeft(sessionLength * 60 * 1000)
playTimer()
} else if (isRunning) {
pauseTimer()
}
}
let playTimer = () => {
setIsRunning(true)
intervalId = setInterval(() => {
setTimeLeft(timeLeft => timeLeft - 1000)
parseToMinuteSeconds(timeLeft)
}, 1000)
}
let pauseTimer = () => {
setIsRunning(false)
clearInterval(intervalId)
}
let resetAll = () => {
setSessionLength(25)
setBreakLength(5)
}
let parseToMinuteSeconds = timeInMilliseconds => {
return //a string with the time in this format 00:00
}
return (
<div className="App">
<Background>
<UpperMetalBand />
<UpperPart />
<LowerPart />
<LowerMetalBand />
<Wrapper>
<Title>Pomodoro</Title>
<Subtitle>TIMER</Subtitle>
<PlayButton
id="start_stop"
onClick = {handlePlayPause}
>
<i className="fa fa-play" />
</PlayButton>
<Reload
onClick={resetAll}
id="reset"
>
<i className="fas fa-sync-alt" />
</Reload>
<Session
setSessionLength={setSessionLength}
sessionLength={sessionLength}
/>
<Break
setBreakLength={setBreakLength}
breakLength={breakLength}
/>
<span id="time-label">
<Timer id="time-left">00:00</Timer>
</span>
</Wrapper>
</Background>
</div>
)
}
Share
Improve this question
edited Mar 27, 2019 at 15:35
Sagiv b.g
31k10 gold badges72 silver badges104 bronze badges
asked Mar 27, 2019 at 14:48
mrcmrc
711 silver badge7 bronze badges
3
- would be nice if you provide a concise run-able example – Sagiv b.g Commented Mar 27, 2019 at 15:18
-
Show us the
clearInterval
method if possible – tomrlh Commented Mar 27, 2019 at 15:23 -
@tomrlh
clearInterval
is part of the browser API, same assetInterval
. see more details – Sagiv b.g Commented Mar 27, 2019 at 15:36
1 Answer
Reset to default 11I think the problem is with how you store the interval id. when using function ponents and we want to store "instance" variables we can use the useRef
hook.
let intervalId = useRef(null)
let handlePlayPause = () => {
if (!isRunning) {
setTimeLeft(sessionLength * 60 * 1000)
playTimer()
} else if (isRunning) {
pauseTimer()
}
}
let playTimer = () => {
setIsRunning(true)
intervalId.current = setInterval(() => {
console.log('interval')
setTimeLeft(timeLeft => timeLeft - 1000)
parseToMinuteSeconds(timeLeft)
}, 1000)
}
let pauseTimer = () => {
setIsRunning(false)
clearInterval(intervalId.current)
}
There is a similar example to your use case on the react docs