UNPKG

@rooks/use-countdown

Version:

Count down to a target timestamp and call callbacks every second (or provided peried)

94 lines (89 loc) 3.25 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react')) : typeof define === 'function' && define.amd ? define(['react'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.useCountdown = factory(global.React)); }(this, (function (react) { 'use strict'; // See also: https://overreacted.io/making-setinterval-declarative-with-react-hooks/ /** * * useInterval hook * * Declaratively creates a setInterval to run a callback after a fixed * amount of time * *@param {funnction} callback - Callback to be fired *@param {number} intervalId - Interval duration in milliseconds after which the callback is to be fired *@param {boolean} startImmediate - Whether the interval should start immediately on initialise *@return {IntervalHandler} */ function useInterval(callback, intervalDuration, startImmediate = false) { const internalIdRef = react.useRef(null); const [isRunning, setIsRunning] = react.useState(startImmediate); const savedCallback = react.useRef(); function start() { if (!isRunning) { setIsRunning(true); } } function stop() { if (isRunning) { setIsRunning(false); } } // Remember the latest callback. react.useEffect(() => { savedCallback.current = callback; }); // Set up the interval. react.useEffect(() => { function tick() { savedCallback.current && savedCallback.current(); } if (intervalDuration !== null && isRunning) { let id = setInterval(tick, intervalDuration); internalIdRef.current = id; return () => { internalIdRef.current = null; clearInterval(id); }; } }, [intervalDuration, isRunning]); let handler; handler = [start, stop, internalIdRef.current]; handler.start = start; handler.stop = stop; handler.intervalId = internalIdRef.current; return handler; } /** * * useCountdown * Easy way to countdown until a given endtime in intervals * @param endTime Time to countdown * @param options Countdown options */ function useCountdown(endTime, options = {}) { const { interval = 1000, onDown, onEnd } = options; const [time, setTime] = react.useState(() => new Date()); const restTime = endTime.getTime() - time.getTime(); const count = restTime > 0 ? Math.ceil(restTime / interval) : 0; useInterval(onTick, count ? interval : null, true); return count; function onTick() { const newTime = new Date(); if (newTime > endTime) { if (onEnd) { onEnd(newTime); } setTime(endTime); return; } if (onDown) { onDown(restTime, newTime); } setTime(newTime); } } return useCountdown; }))); //# sourceMappingURL=index.js.map