please how do i fix my react timer, it stays at 1 π
Damilola Ogunleye@dami_learns
good evening everyone ππΎ i'm building a pomodoro timer for my portfolio. the seconds go from 0 to 1 and then it just stays at 1 forever. no error in the console. i just came across something called "stale closure" but i don't understand it. here is my code:
import { useEffect, useState } from 'react'
function Timer() {
const [seconds, setSeconds] = useState(0)
useEffect(() => {
const id = setInterval(() => {
setSeconds(seconds + 1)
}, 1000)
}, [])
return <p>{seconds}s</p>
}
please what am i doing wrong? e ku ise in advance ππΎ
Accepted answer
ah this one na classic. the interval callback catch "seconds" when it was 0, and because your useEffect get [] e no go run again, so every second e dey do 0 + 1. forever 1 π
fix am like this:
useEffect(() => {
const id = setInterval(() => {
setSeconds((s) => s + 1)
}, 1000)
return () => clearInterval(id)
}, [])
setSeconds((s) => s + 1) means "take whatever the current value is and add 1", so e no care about the old captured value.
the clearInterval part is important too. without it, StrictMode go run your effect twice in dev, you go get two intervals, timer go dey count double speed and you go think say na witchcraft
Get the best of #rerender-anonymous weekly
One email each Monday with the most useful posts. No spam; unsubscribe in one click.
Comments
Sign in to join the conversation.
Sign in to commentAccepted answer
Kelechi Nnaji@abeg_compile
ah this one na classic. the interval callback catch "seconds" when it was 0, and because your useEffect get [] e no go run again, so every second e dey do 0 + 1. forever 1 π
fix am like this:
useEffect(() => {
const id = setInterval(() => {
setSeconds((s) => s + 1)
}, 1000)
return () => clearInterval(id)
}, [])
setSeconds((s) => s + 1) means "take whatever the current value is and add 1", so e no care about the old captured value.
the clearInterval part is important too. without it, StrictMode go run your effect twice in dev, you go get two intervals, timer go dey count double speed and you go think say na witchcraft
Damilola Ogunleye@dami_learns
AHHH it's working!!! ππΎ and you're right, before i added clearInterval it was counting 2 at a time and i thought i was going mad π thank you so much abeg_compile, i didn't know you were serious like this
Oluwatobi Adeyemi@tobi_freelance
Dami, well done for posting the code with the question, that's how you get fast answers. Next one: make it pause and resume, put it on your portfolio and send me the link. I have a small client who needs a junior for something like this π
Kuya Migs@kuya_migs_codes
Ganda ng explanation ni abeg π₯ Dami, think of a stale closure like a photo: the function keeps a photo of seconds from when it was created, not the live value. The (s) => s + 1 version asks React for the live one.
Achieng Owino@achieng_devrel
Love seeing this. Dami, keep posting your progress, small wins compound.