JAVASCRIPT
Custom useCountdown Hook for Timer Functionality
A flexible React custom hook to create and manage countdown timers, perfect for displaying time remaining, limited-time offers, or game mechanics.
import { useState, useEffect, useCallback } from 'react';
const useCountdown = (initialSeconds = 60, autoStart = false) => {
const [secondsLeft, setSecondsLeft] = useState(initialSeconds);
const [isRunning, setIsRunning] = useState(autoStart);
const start = useCallback(() => setIsRunning(true), []);
const stop = useCallback(() => setIsRunning(false), []);
const reset = useCallback(() => {
setSecondsLeft(initialSeconds);
setIsRunning(false);
}, [initialSeconds]);
useEffect(() => {
if (!isRunning) {
return;
}
if (secondsLeft <= 0) {
setIsRunning(false);
return;
}
const timerId = setInterval(() => {
setSecondsLeft(prevSeconds => prevSeconds - 1);
}, 1000);
return () => clearInterval(timerId); // Cleanup on unmount or if dependencies change
}, [isRunning, secondsLeft]); // Re-run effect when running status or secondsLeft changes
return { secondsLeft, isRunning, start, stop, reset };
};
export default useCountdown;
// How to use:
// import useCountdown from './useCountdown';
// function CountdownDisplay() {
// const { secondsLeft, isRunning, start, stop, reset } = useCountdown(10, true);
// return (
// <div>
// <p>Time left: {secondsLeft} seconds</p>
// <p>Status: {isRunning ? 'Running' : 'Stopped'}</p>
// <button onClick={start} disabled={isRunning}>Start</button>
// <button onClick={stop} disabled={!isRunning}>Stop</button>
// <button onClick={reset}>Reset</button>
// </div>
// );
// }
How it works: This custom hook provides robust countdown timer functionality. It manages the `secondsLeft` and `isRunning` states. The `useEffect` hook handles the `setInterval` logic: when `isRunning` is true and `secondsLeft` is greater than zero, it decrements the `secondsLeft` every second. The effect cleans up the `setInterval` using `clearInterval` when the component unmounts or `isRunning` becomes false or `secondsLeft` reaches zero. It also exposes `start`, `stop`, and `reset` functions to control the timer, making it highly reusable for various timer-related UI elements.