import { useState, useEffect, useRef, useCallback } from 'react'; /** * useTimeout * * @param {Function} cb - callback function inside setTimeout * @param {number} delay - delay in ms * @param {boolean} [immediate] - determines whether the timeout is invoked immediately * @returns {Function|undefined} */ export function useTimeout(cb, delay, immediate = true) { const saveCb = useRef(); const [timeoutId, setTimeoutId] = useState(null); useEffect(() => { saveCb.current = cb; }, [cb]); useEffect(() => { if (timeoutId !== 'start') { return undefined; } const id = setTimeout(() => { saveCb.current(); }, delay); setTimeoutId(id); return () => { clearTimeout(timeoutId); }; }, [delay, timeoutId]); const startTimeout = useCallback(() => { clearTimeout(timeoutId); setTimeoutId('start'); }, [timeoutId]); if (immediate) { startTimeout(); } return startTimeout; }