How to Implement a Countdown Functionality in React
setTimeout
Disadvantages
- Inaccurate timing as it triggers every 1000 milliseconds.
- Frequent triggering of useEffect leading to unmounting and re-rendering.
jsx
const [countdown, setCountdown] = useState(0);
const startCountdown = () => {
setCountdown(10);
};
useEffect(() => {
if (countdown <= 0) {
return;
}
const timeOut = setTimeout(() => {
setCountdown((v) => v - 1);
}, 1000);
return () => {
clearTimeout(timeOut);
};
}, [countdown]);
<div>
<div>{`the state is ${countdown}`}</div>
<button
type="button"
onClick={() => {
startCountdown();
}}
>
start
</button>
</div>
setInterval
Using count variable
Disadvantages
- Cannot be reused multiple times; once the countdown ends, it cannot be reused.
jsx
const timerRef = useRef<any>(null);
const [reducerState, reducerDispatch] = useReducer((state) => {
if (state === 1) {
clearInterval(timerRef.current);
}
return state - 1;
}, 10);
const startCountdown = () => {
timerRef.current = setInterval(() => {
reducerDispatch();
}, 1000);
};
<div>
<div>{`the state is ${reducerState}`}</div>
<button
type="button"
onClick={() => {
startCountdown();
}}
>
start
</button>
</div>