4

I have a timer MM:SS that is counting upwards to a set time of MM:SS. i.e. from 00:00 to 45:00.

My state is current set at.

  const [currentTime, setCurrentTime] = useState<CurrentTime>({
    minutes: 0,
    seconds: 58,
  });

My useEffect timer to continiously update time is set up as...

 useEffect(() => {
  let interval: any;

  if (!finished) {
  interval = setInterval(() => {
    if (currentTime.seconds === 60) {
      setCurrentTime({
        ...currentTime,
        minutes: currentTime.minutes++,
        seconds: 0,
      });
    } else {
      setCurrentTime({
        ...currentTime,
        minutes: currentTime.minutes,
        seconds: currentTime.seconds++,
      });
    }

   }, 1000);
    } else {
      clearInterval(interval);
    }

    return () => clearInterval(interval);
  }, [finished]);

The problem I have is that when the seconds reach 60. The minute property updates, but the seconds property never updates and is always stuck at 60, leading to a continuous output of 01:00, 02:00, 03:00, 04:00 05:00, ..., in the console.

What do I need to do so that when 60 seconds is reached, the minute goes up by 1 and the seconds goes back to 0 at the same time.

1 Answer 1

2

Looks like you are mutating state and have an issue with stale enclosure. Use a functional state update to correctly update from the previous state. Move the conditional check on currentTime.seconds into the functional update. You will also want to check and "reset" the seconds to 0 when 59 seconds is reached so that on the next "tick" it is 0 instead of reaching 60.

useEffect(() => {
  let interval;

  if (!finished) {
    interval = setInterval(() => {
      setCurrentTime((currentTime) => {
        if (currentTime.seconds === 59) {
          return {
            ...currentTime,
            minutes: currentTime.minutes + 1,
            seconds: 0
          };
        } else {
          return {
            ...currentTime,
            minutes: currentTime.minutes,
            seconds: currentTime.seconds + 1
          };
        }
      });
    }, 1000);
  } else {
    clearInterval(interval);
  }

  return () => clearInterval(interval);
}, [finished]);

Edit react-timer-using-sestate-and-interval-not-working

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the response! I managed to get it working by adding a reference to the previous state when attempting to change the state, just like you said, AND adding currentTime as a dependency in the useEffect dependency array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.