35 lines
802 B
TypeScript
35 lines
802 B
TypeScript
|
import { useEffect, useRef } from "react";
|
||
|
|
||
|
export default function useSetTimeout() {
|
||
|
const didUnmountRef = useRef(false);
|
||
|
const { current: scheduledTimers } = useRef(new Set<number>());
|
||
|
|
||
|
useEffect(
|
||
|
() => () => {
|
||
|
didUnmountRef.current = true;
|
||
|
clearAll();
|
||
|
},
|
||
|
[]
|
||
|
);
|
||
|
|
||
|
function clearAll() {
|
||
|
scheduledTimers.forEach((timer) => clearTimeout(timer));
|
||
|
scheduledTimers.clear();
|
||
|
}
|
||
|
|
||
|
return function scheduleTimeout(callback: () => void, delay: number) {
|
||
|
if (didUnmountRef.current) {
|
||
|
throw new Error("Can't schedule a timeout on an unmounted component.");
|
||
|
}
|
||
|
|
||
|
const timer = Number(setTimeout(handleCallback, delay));
|
||
|
|
||
|
scheduledTimers.add(timer);
|
||
|
|
||
|
function handleCallback() {
|
||
|
scheduledTimers.delete(timer);
|
||
|
callback();
|
||
|
}
|
||
|
};
|
||
|
}
|