( callback: CallbackFn<T>, initialTimer: number, )
| 10 | clearTimer: () => void; |
| 11 | } |
| 12 | export default function useTimer<T = unknown>( |
| 13 | callback: CallbackFn<T>, |
| 14 | initialTimer: number, |
| 15 | ): UseTimerReturnProps { |
| 16 | const initRef = useRef(false); |
| 17 | const [timer, setTimer] = useState(initialTimer); |
| 18 | const [runTimer, clearTimer] = useDebounceFn(() => { |
| 19 | if (timer > 0) { |
| 20 | setTimer((_timer) => _timer - 1); |
| 21 | runTimer(); |
| 22 | } else { |
| 23 | if (callback) { |
| 24 | callback(); |
| 25 | } |
| 26 | clearTimer(); |
| 27 | } |
| 28 | }, 1000); |
| 29 | |
| 30 | // if the initial timer is greater than 0, then we start it on load. |
| 31 | // we utilized a `ref` to ensure this will only be triggered once |
| 32 | useEffect(() => { |
| 33 | if (initRef.current) { |
| 34 | return; |
| 35 | } |
| 36 | |
| 37 | initRef.current = true; |
| 38 | |
| 39 | if (initialTimer > 0) { |
| 40 | runTimer(); |
| 41 | } |
| 42 | }, [initialTimer, runTimer]); |
| 43 | |
| 44 | return useMemo( |
| 45 | () => ({ |
| 46 | timer, |
| 47 | setTimer, |
| 48 | runTimer, |
| 49 | clearTimer, |
| 50 | }), |
| 51 | [timer, setTimer, runTimer, clearTimer], |
| 52 | ); |
| 53 | } |
no test coverage detected