VayuUI

useCountdown

A hook to manage countdown timers with start, pause, and reset functionality.

The useCountdown hook provides a simple way to implement a countdown timer in your React components. It handles the interval logic and state management for you.

Demo

10s

Source Code

Copy this code into src/hooks/useCountdown.ts:

import { useState, useEffect, useRef } from 'react';

interface UseCountdownOptions {
  seconds: number;
  interval?: number;
  onTick?: (timeLeft: number) => void;
  onComplete?: () => void;
}

export const useCountdown = ({
  seconds,
  interval = 1000,
  onTick,
  onComplete,
}: UseCountdownOptions) => {
  const [timeLeft, setTimeLeft] = useState(seconds);
  const [isRunning, setIsRunning] = useState(false);
  const intervalRef = useRef<NodeJS.Timeout | null>(null);

  useEffect(() => {
    if (isRunning && timeLeft > 0) {
      intervalRef.current = setInterval(() => {
        setTimeLeft((prev) => {
          const newTime = prev - 1;
          if (onTick) onTick(newTime);
          if (newTime <= 0) {
            clearInterval(intervalRef.current!);
            setIsRunning(false);
            if (onComplete) onComplete();
          }
          return newTime > 0 ? newTime : 0;
        });
      }, interval);
    }
    return () => {
      if (intervalRef.current) clearInterval(intervalRef.current);
    };
  }, [isRunning, timeLeft, interval, onTick, onComplete]);

  const start = () => {
    if (!isRunning) {
      setIsRunning(true);
    }
  };

  const pause = () => {
    if (isRunning) {
      if (intervalRef.current) clearInterval(intervalRef.current);
      setIsRunning(false);
    }
  };

  const reset = () => {
    if (intervalRef.current) clearInterval(intervalRef.current);
    setTimeLeft(seconds);
    setIsRunning(false);
  };

  return { timeLeft, start, pause, reset, isRunning };
};

Usage

import { useCountdown } from '@/hooks/useCountdown';

const CountdownComponent = () => {
  const { timeLeft, start, pause, reset, isRunning } = useCountdown({
    seconds: 60,
    onComplete: () => alert("Time's up!"),
  });

  return (
    <div>
      <p>Time Left: {timeLeft}s</p>
      <button onClick={start} disabled={isRunning}>
        Start
      </button>
      <button onClick={pause} disabled={!isRunning}>
        Pause
      </button>
      <button onClick={reset}>Reset</button>
    </div>
  );
};

API Reference

Options

PropertyTypeDefaultDescription
secondsnumberRequiredThe initial time in seconds.
intervalnumber1000The interval in milliseconds (default: 1 second).
onTick(timeLeft: number) => voidundefinedCallback function called on every tick.
onComplete() => voidundefinedCallback function called when countdown reaches 0.

Return Value

PropertyTypeDescription
timeLeftnumberThe current time left in seconds.
start() => voidFunction to start the countdown.
pause() => voidFunction to pause the countdown.
reset() => voidFunction to reset the countdown to original seconds.
isRunningbooleanBoolean indicating if the countdown is active.

On this page