typescriptintermediate
useCountdown Hook
Countdown timer hook with start, pause, reset, and formatted time remaining output.
typescriptPress ⌘/Ctrl + Shift + C to copy
import { useState, useRef, useCallback } from 'react';
export function useCountdown(initialSeconds: number) {
const [remaining, setRemaining] = useState(initialSeconds);
const [isRunning, setIsRunning] = useState(false);
const intervalRef = useRef<ReturnType<typeof setInterval>>();
const start = useCallback(() => {
if (isRunning || remaining <= 0) return;
setIsRunning(true);
intervalRef.current = setInterval(() => {
setRemaining(prev => {
if (prev <= 1) {
clearInterval(intervalRef.current);
setIsRunning(false);
return 0;
}
return prev - 1;
});
}, 1000);
}, [isRunning, remaining]);
const pause = useCallback(() => {
clearInterval(intervalRef.current);
setIsRunning(false);
}, []);
const reset = useCallback(() => {
clearInterval(intervalRef.current);
setIsRunning(false);
setRemaining(initialSeconds);
}, [initialSeconds]);
const minutes = Math.floor(remaining / 60);
const seconds = remaining % 60;
const formatted = `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
return { remaining, formatted, isRunning, start, pause, reset };
}Use Cases
- OTP expiry timers
- Quiz time limits
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
typescriptintermediate
useInterval Hook
Declarative setInterval hook that handles cleanup and dynamic delay changes safely.
Best for: Polling APIs
#hooks#timer
typescriptbeginner
useTimeout Hook
Declarative setTimeout hook with automatic cleanup and reset capabilities.
Best for: Auto-dismiss notifications
#hooks#timer
typescriptintermediate
useFetch — Generic Data Fetching Hook
Custom React hook for data fetching with loading, error, and refetch states using the Fetch API.
Best for: API data fetching
#hooks#fetch
typescriptbeginner
useDebounce — Debounced Value Hook
Debounce any rapidly-changing value with a configurable delay. Useful for search inputs and resize handlers.
Best for: Search-as-you-type
#hooks#debounce