@mirawision/reactive-hooks
Version:
A comprehensive collection of 50+ React hooks for state management, UI interactions, device APIs, async operations, drag & drop, audio/speech, and more. Full TypeScript support with SSR safety.
95 lines (94 loc) • 3.03 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.useClock = useClock;
const react_1 = require("react");
const use_is_mounted_1 = require("./use-is-mounted");
const use_toggle_1 = require("./use-toggle");
/**
* Hook that manages timer functionality with enable/disable/cooldown features
*
* @param timeout - Timeout interval in milliseconds
* @param initCb - Initial callback function
* @returns Tuple with clock controls and callback setter
*/
function useClock(timeout, initCb = () => { }) {
const [isClockWorking, handleIsClockWorking] = (0, use_toggle_1.useToggle)(false);
const [cb, setCb] = (0, react_1.useState)(() => initCb);
const isMounted = (0, use_is_mounted_1.useIsMounted)();
const timerRef = (0, react_1.useRef)(null);
const cooldownRef = (0, react_1.useRef)(null);
const setCooldown = (ms, condition) => {
handleIsClockWorking.disable();
if (cooldownRef.current) {
clearTimeout(cooldownRef.current);
}
cooldownRef.current = setTimeout(() => {
handleDisable();
if (!isMounted() || !condition())
return;
handleIsClockWorking.enable();
}, ms);
};
const handleDisable = () => {
handleIsClockWorking.disable();
if (timerRef.current) {
clearTimeout(timerRef.current);
timerRef.current = null;
}
if (cooldownRef.current) {
clearTimeout(cooldownRef.current);
cooldownRef.current = null;
}
};
const handleEnable = () => {
if (cooldownRef.current) {
clearTimeout(cooldownRef.current);
}
handleIsClockWorking.enable();
};
const handleStop = () => {
handleDisable();
};
(0, react_1.useEffect)(() => {
if (!cb) {
throw new Error('No function to call');
}
if (timerRef.current) {
clearTimeout(timerRef.current);
}
if (!isClockWorking)
return;
const tick = () => {
cb();
timerRef.current = setTimeout(tick, timeout);
};
timerRef.current = setTimeout(tick, timeout);
return () => {
if (timerRef.current) {
clearTimeout(timerRef.current);
timerRef.current = null;
}
};
}, [cb, isClockWorking, timeout]);
(0, react_1.useEffect)(() => {
return () => {
if (timerRef.current) {
clearTimeout(timerRef.current);
}
if (cooldownRef.current) {
clearTimeout(cooldownRef.current);
}
};
}, []);
return [
{
enable: handleEnable,
disable: handleDisable,
stop: handleStop,
toggle: handleIsClockWorking.toggle,
cooldown: setCooldown,
isEnabled: isClockWorking,
},
(callback) => setCb(() => callback),
];
}