From cb17e587f5289f5fd8f7c1556903ebbcebc09067 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=B3=E5=BB=B7=E5=AE=89?= <73953029+nrps9909@users.noreply.github.com> Date: Thu, 27 Aug 2026 00:48:37 +0800 Subject: [PATCH] fix(useDelayState): cancel pending updates on unmount --- src/hooks/useDelayState.ts | 2 ++ tests/useDelayState.test.tsx | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/hooks/useDelayState.ts b/src/hooks/useDelayState.ts index 978f7421..e30df3d8 100644 --- a/src/hooks/useDelayState.ts +++ b/src/hooks/useDelayState.ts @@ -37,6 +37,8 @@ export default function useDelayState( } }); + React.useEffect(() => cancelPending, [cancelPending]); + const setDelayValue = useEvent>( (nextValue, immediatelyOrDelay) => { const delayConfig = immediatelyOrDelay || { frame: 1 }; diff --git a/tests/useDelayState.test.tsx b/tests/useDelayState.test.tsx index 60c8131f..abf7dbff 100644 --- a/tests/useDelayState.test.tsx +++ b/tests/useDelayState.test.tsx @@ -121,6 +121,21 @@ describe('useDelayState', () => { expect(result.current[0]).toBe(2); }); + it.each([ + ['frame', { frame: 2 }], + ['timeout', { ms: 100 }], + ] as const)('cancels a pending %s update on unmount', (_, delay) => { + const { result, unmount } = renderHook(() => useDelayState(0)); + + act(() => { + result.current[1](1, delay); + }); + expect(jest.getTimerCount()).toBe(1); + + unmount(); + expect(jest.getTimerCount()).toBe(0); + }); + it('supports updater function', () => { const { result } = renderHook(() => useDelayState(1));