so I have a react modal which has a countdown timer. The timer doesn’t seem to work on Chrome but works on Firefox. On Chrome timer starts to count down but decreases its ticking pase when it ticks for about 20 seconds.
This is the current implementation of the modal and the timer.
import React, {useState, useEffect } from 'react';
import BaseModal from './Index';
export default function OtpModal(props: Props) {
const [timeLeft, setTimeLeft] = useState<number>(120);
useEffect(() => {
const intervalId = setInterval(() => {
console.log('tick', timeLeft);
setTimeLeft(timeLeft - 1);
}, 1000);
return () => clearInterval(intervalId);
}, [timeLeft]);
return (
<BaseModal>
<div>
OTP timeout in{' '}
<span style={{fontWeight: '500'}}>
{Math.floor(timeLeft / 60)}:
{(timeLeft % 60).toString().padStart(2, '0')}
</span>
</div>
</BaseModal>
)
}
3
Answers
You are running your useEffect and setting a new timer at each second.
Maybe it is causing issue if there is timer throttling.
You can set only one timer and run once your useEffect like that:
When we run
clearInterval
andsetInterval
, their timing shifts. If we re-render and re-apply effects too often, the interval never gets a chance to fire!I would recommend studying this blog post about problems with the
setInterval
and react hooks. The blog post suggests creating a custom hook(useInterval
) as follows:Usage
It would be easier to create a hook called
useTimer
to handle counting down the time. That way, each<Timer>
only needs to know the time it will render.