Skip to content

Instantly share code, notes, and snippets.

@orenmizr
Created July 12, 2023 11:23
Show Gist options
  • Save orenmizr/e09f6ac515666b42c0a1dc6f187ef034 to your computer and use it in GitHub Desktop.
Save orenmizr/e09f6ac515666b42c0a1dc6f187ef034 to your computer and use it in GitHub Desktop.
counter
import { useState, useRef, useEffect, useCallback } from 'react';
interface CountdownOptions {
onComplete: () => void;
onTick?: () => void;
interval: number | null;
}
export function useCountdown(endTime: number, options: CountdownOptions) {
const [count, setCount] = useState<number | null>(null);
const intervalIdRef = useRef<number | null>(null);
const handleClearInterval = useCallback(() => {
window.clearInterval(intervalIdRef.current!);
}, []);
const onTick = useCallback(() => {
if (count === 0) {
handleClearInterval();
options.onComplete();
} else if (typeof count === 'number') {
setCount(count - 1);
options?.onTick?.();
}
}, [count, handleClearInterval, options]);
useEffect(() => {
intervalIdRef.current = window.setInterval(() => {
onTick();
}, options.interval!);
return () => handleClearInterval();
}, [onTick, options.interval, handleClearInterval]);
useEffect(() => {
setCount(Math.round((endTime - Date.now()) / options.interval!));
}, [endTime, options.interval]);
return count;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment