Skip to content
question

please how do i fix my react timer, it stays at 1 😭

Damilola Ogunleye@dami_learns

October 19, 2026 Β· 1 min read

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

Kelechi Nnaji#4 in Rerender Anonymous17 likes

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

View in the thread

Get the best of #rerender-anonymous weekly

One email each Monday with the most useful posts. No spam; unsubscribe in one click.

Comments

7

Sign in to join the conversation.

Sign in to comment

Accepted answer

Kelechi Nnaji@abeg_compile#4 in Rerender Anonymous
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
17 net votes
Damilola Ogunleye@dami_learns#2 in Rerender Anonymous
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
0 net votes
Kelechi Nnaji@abeg_compile#4 in Rerender Anonymous
memes by day, react by night 😎 abeg no tell anybody
1 net votes
Oluwatobi Adeyemi@tobi_freelance1 rep in Rerender Anonymous
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 πŸ‘€
4 net votes
Damilola Ogunleye@dami_learns#2 in Rerender Anonymous
uncle tobi!! okay sir, pause and resume by tomorrow πŸ™πŸΎπŸ™πŸΎ
3 net votes
Kuya Migs@kuya_migs_codes3 rep in Rerender Anonymous
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.
1 net votes
Achieng Owino@achieng_devrel1 rep in Rerender Anonymous
Love seeing this. Dami, keep posting your progress, small wins compound.
1 net votes