diff --git a/packages/usehooks-ts/src/useDebounceCallback/useDebounceCallback.test.ts b/packages/usehooks-ts/src/useDebounceCallback/useDebounceCallback.test.ts index b2f9ee97..18a27e0e 100644 --- a/packages/usehooks-ts/src/useDebounceCallback/useDebounceCallback.test.ts +++ b/packages/usehooks-ts/src/useDebounceCallback/useDebounceCallback.test.ts @@ -107,4 +107,30 @@ describe('useDebounceCallback()', () => { // The callback should be invoked immediately after flushing expect(debouncedCallback).toHaveBeenCalled() }) + + it('should maintain debouncing across rerenders with an unstable options object', () => { + const delay = 500 + const callback = vitest.fn() + + const { result: debouncedCallback, rerender } = renderHook(() => + useDebounceCallback(callback, delay, { leading: false }), + ) + + act(() => { + debouncedCallback.current('first') + }) + + vitest.advanceTimersByTime(200) + + // Simulate a component rerender, which creates a new instance of the options object + rerender() + + act(() => { + debouncedCallback.current('second') + }) + + vitest.advanceTimersByTime(350) + + expect(callback).not.toHaveBeenCalled() + }) }) diff --git a/packages/usehooks-ts/src/useDebounceCallback/useDebounceCallback.ts b/packages/usehooks-ts/src/useDebounceCallback/useDebounceCallback.ts index 94f9065a..420b3c8d 100644 --- a/packages/usehooks-ts/src/useDebounceCallback/useDebounceCallback.ts +++ b/packages/usehooks-ts/src/useDebounceCallback/useDebounceCallback.ts @@ -104,12 +104,12 @@ export function useDebounceCallback ReturnType>( } return wrappedFunc - }, [func, delay, options]) + }, [func, delay]) // Update the debounced function ref whenever func, wait, or options change useEffect(() => { debouncedFunc.current = debounce(func, delay, options) - }, [func, delay, options]) + }, [func, delay]) return debounced }