Skip to content

Instantly share code, notes, and snippets.

@markusand
Created May 3, 2024 19:10
Show Gist options
  • Save markusand/62df4b2cd1f02ac5bcab1bf4f311b97b to your computer and use it in GitHub Desktop.
Save markusand/62df4b2cd1f02ac5bcab1bf4f311b97b to your computer and use it in GitHub Desktop.
[React] useTimeout hook
import { useState, useEffect } from 'react';
export type TimeoutOptions = {
initial: number;
auto?: boolean;
interval?: number;
onFinish?: () => void;
};
export const useTimeout = (options?: TimeoutOptions) => {
const { initial = 10_000, interval = 1000, onFinish } = options ?? {};
const [time, setTime] = useState(initial);
const [isRunning, setIsRunning] = useState(false);
useEffect(() => {
if (!isRunning) return;
if (time <= 0) return finish();
const timer = setTimeout(() => {
setTime(prevTime => prevTime - interval);
}, interval);
return () => clearTimeout(timer);
}, [isRunning, time, interval]);
const finish = () => {
onFinish?.();
setIsRunning(false);
};
const start = (startAt = time) => {
setTime(startAt);
setIsRunning(true);
};
const resume = () => time && setIsRunning(true);
const stop = () => setIsRunning(false);
const reset = () => {
setTime(initial);
setIsRunning(false);
};
const restart = () => start(initial);
return { time, isRunning, start, stop, resume, restart, reset };
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment