setTimeout out of sync when closing site

Viewed 40

setTimeout function works in line with my other setTimeout function as long as I keep the window open. However, if I go to another tab/window and then come back to the timer, it will be out of sync with the other countdown.

This is the first timer:

const [isDisabled, setIsDisabled] = useState(false);

    const handleOnClickUp = () => {
    setIsDisabled(true);
    setTimeout(() => setIsDisabled(false), 60000);}

Second Timer:

 const [counter, setCounter] = useState(60);

     if (isDisabled == true) {
    setTimeout(() => setCounter(counter - 1), 1000);
  }

  if (counter == 0) {
    setCounter(60);
  }

Returning:

return (
    <>
      <div>{counter}</div>
      <button
        disabled={isDisabled}
        onClick={handleOnClickUp}
        className="bg-gray-500"
      >
        Up
      </button>
    
    </>
  );

TLDR: How can I sync the two timers together with no problems?

1 Answers

Chrome and most other browsers have low-priority execution when a tab is inactive, i.e., setCounter is not being called as frequently. I faced a similar issue a while back and then shifted to using requestAnimationFrame.

Here's the example code from React:

const countDown = 30 * 1000;
const defaultTargetDate = new Date().getTime();

const [targetDate, setTargetDate] = useState(new Date(defaultTargetDate));

const [remainingSeconds, setRemainingSeconds] = useState(countDown / 1000);

const countItDown = () =>
  requestAnimationFrame(() => {
    const diff = Math.floor((targetDate - new Date().getTime()) / 1000);
    setRemainingSeconds(diff);
    if (diff > 0) {
      countItDown();
    }
  });

useEffect(() => {
  countItDown();
}, [targetDate]);

Related