2022-02-23 10:29:50 +00:00
|
|
|
import { useEffect, useRef } from "react";
|
|
|
|
|
|
|
|
export default function useSetTimeout() {
|
|
|
|
const didUnmountRef = useRef(false);
|
|
|
|
const { current: scheduledTimers } = useRef(new Set<number>());
|
|
|
|
|
2023-07-28 09:41:40 +00:00
|
|
|
useEffect(() => {
|
|
|
|
didUnmountRef.current = false;
|
|
|
|
|
|
|
|
return () => {
|
2022-02-23 10:29:50 +00:00
|
|
|
didUnmountRef.current = true;
|
|
|
|
clearAll();
|
2023-07-28 09:41:40 +00:00
|
|
|
};
|
|
|
|
}, []);
|
2022-02-23 10:29:50 +00:00
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
2022-02-23 14:46:26 +00:00
|
|
|
|
|
|
|
return function cancelTimeout() {
|
|
|
|
clearTimeout(timer);
|
|
|
|
scheduledTimers.delete(timer);
|
|
|
|
};
|
2022-02-23 10:29:50 +00:00
|
|
|
};
|
|
|
|
}
|