From 16a08a8cb01927791fc5d74d2a66fb81ca30af9f Mon Sep 17 00:00:00 2001 From: kyletsang <6854874+kyletsang@users.noreply.github.com> Date: Sat, 3 Feb 2024 23:18:59 -0800 Subject: [PATCH] fix(useDebouncedCallback): fix behavior in strict mode --- src/useDebouncedCallback.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/useDebouncedCallback.ts b/src/useDebouncedCallback.ts index 76ba990..e0bd617 100644 --- a/src/useDebouncedCallback.ts +++ b/src/useDebouncedCallback.ts @@ -1,7 +1,7 @@ -import { useCallback, useMemo, useRef } from 'react' +import { useMemo, useRef } from 'react' import useTimeout from './useTimeout' -import useMounted from './useMounted' import useEventCallback from './useEventCallback' +import useWillUnmount from './useWillUnmount' export interface UseDebouncedCallbackOptions { wait: number @@ -55,6 +55,8 @@ function useDebouncedCallback any>( const isTimerSetRef = useRef(false) const lastArgsRef = useRef(null) + // Use any to bypass type issue with setTimeout. + const timerRef = useRef(0) const handleCallback = useEventCallback(fn) @@ -69,6 +71,11 @@ function useDebouncedCallback any>( const timeout = useTimeout() + useWillUnmount(() => { + clearTimeout(timerRef.current) + isTimerSetRef.current = false + }) + return useMemo(() => { const hasMaxWait = !!maxWait @@ -161,14 +168,14 @@ function useDebouncedCallback any>( if (hasMaxWait) { // Handle invocations in a tight loop. isTimerSetRef.current = true - setTimeout(timerExpired, wait) + timerRef.current = setTimeout(timerExpired, wait) return invokeFunc(lastCallTimeRef.current) } } if (!isTimerSetRef.current) { isTimerSetRef.current = true - setTimeout(timerExpired, wait) + timerRef.current = setTimeout(timerExpired, wait) } return returnValueRef.current