State
useCountdown
Self-stopping countdown or count-up timer.
Demo
live · imported from hookli
10
import { useCountdown } from "hookli";
export function Demo() {
const [count, { startCountdown, stopCountdown, resetCountdown }] = useCountdown({
countStart: 10,
intervalMs: 1000,
});
return (
<div>
<p>{count}</p>
<button onClick={startCountdown}>Start</button>
<button onClick={stopCountdown}>Pause</button>
<button onClick={resetCountdown}>Reset</button>
</div>
);
}Usage
import { useCountdown } from "hookli";
export function Demo() {
const [count, { startCountdown, stopCountdown, resetCountdown }] = useCountdown({
countStart: 10,
intervalMs: 1000,
});
return (
<div>
<p>{count}</p>
<button onClick={startCountdown}>Start</button>
<button onClick={stopCountdown}>Pause</button>
<button onClick={resetCountdown}>Reset</button>
</div>
);
}API
useCountdown(options: UseCountdownOptions): [number, UseCountdownActions]Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| options | UseCountdownOptions | — | Configures the timer — start value, tick interval, direction and stop value. See below. |
Returns
| Name | Type | Description |
|---|---|---|
| [0] count | number | The current count. Ticks by ±1 every intervalMs while running. |
| [1] actions | UseCountdownActions | Start, pause and reset controls — see below. |
UseCountdownOptions
The single options argument.
| Name | Type | Description |
|---|---|---|
| countStart | number | The value the countdown starts from. |
| intervalMs | number | Milliseconds between ticks. Defaults to 1000. |
| isIncrement | boolean | Count up instead of down. Defaults to false. |
| countStop | number | The value at which the timer stops itself. Defaults to 0. |
UseCountdownActions
The second tuple element — the timer controls.
| Name | Type | Description |
|---|---|---|
| startCountdown | () => void | Starts (or resumes) the timer. |
| stopCountdown | () => void | Pauses the timer without resetting the count. |
| resetCountdown | () => void | Stops the timer and resets the count to countStart. |
Hook
The implementation, straight from hookli. Copy it, or install the package.
import { useCallback, useEffect, useRef, useState } from "react";
export interface UseCountdownOptions {
countStart: number;
intervalMs?: number;
isIncrement?: boolean;
countStop?: number;
}
export interface UseCountdownActions {
startCountdown: () => void;
stopCountdown: () => void;
resetCountdown: () => void;
}
export const useCountdown = ({
countStart,
intervalMs = 1000,
isIncrement = false,
countStop = 0,
}: UseCountdownOptions): [number, UseCountdownActions] => {
const [count, setCount] = useState(countStart);
const [isRunning, setIsRunning] = useState(false);
const startCountdown = useCallback(() => setIsRunning(true), []);
const stopCountdown = useCallback(() => setIsRunning(false), []);
const resetCountdown = useCallback(() => {
setIsRunning(false);
setCount(countStart);
}, [countStart]);
const tick = useRef(() => {});
tick.current = () => {
setCount((prev) => (isIncrement ? prev + 1 : prev - 1));
};
useEffect(() => {
if (isRunning && count === countStop) {
setIsRunning(false);
}
}, [count, countStop, isRunning]);
useEffect(() => {
if (!isRunning) return;
const id = setInterval(() => tick.current(), intervalMs);
return () => clearInterval(id);
}, [isRunning, intervalMs]);
return [count, { startCountdown, stopCountdown, resetCountdown }];
};