1- import { useCallback , useMemo , useRef } from 'react'
1+ import { useMemo , useRef } from 'react'
22import useTimeout from './useTimeout'
3- import useMounted from './useMounted'
43import useEventCallback from './useEventCallback'
4+ import useWillUnmount from './useWillUnmount'
55
66export interface UseDebouncedCallbackOptions {
77 wait : number
@@ -55,6 +55,8 @@ function useDebouncedCallback<TCallback extends (...args: any[]) => any>(
5555
5656 const isTimerSetRef = useRef ( false )
5757 const lastArgsRef = useRef < unknown [ ] | null > ( null )
58+ // Use any to bypass type issue with setTimeout.
59+ const timerRef = useRef < any > ( 0 )
5860
5961 const handleCallback = useEventCallback ( fn )
6062
@@ -69,6 +71,11 @@ function useDebouncedCallback<TCallback extends (...args: any[]) => any>(
6971
7072 const timeout = useTimeout ( )
7173
74+ useWillUnmount ( ( ) => {
75+ clearTimeout ( timerRef . current )
76+ isTimerSetRef . current = false
77+ } )
78+
7279 return useMemo ( ( ) => {
7380 const hasMaxWait = ! ! maxWait
7481
@@ -161,14 +168,14 @@ function useDebouncedCallback<TCallback extends (...args: any[]) => any>(
161168 if ( hasMaxWait ) {
162169 // Handle invocations in a tight loop.
163170 isTimerSetRef . current = true
164- setTimeout ( timerExpired , wait )
171+ timerRef . current = setTimeout ( timerExpired , wait )
165172 return invokeFunc ( lastCallTimeRef . current )
166173 }
167174 }
168175
169176 if ( ! isTimerSetRef . current ) {
170177 isTimerSetRef . current = true
171- setTimeout ( timerExpired , wait )
178+ timerRef . current = setTimeout ( timerExpired , wait )
172179 }
173180
174181 return returnValueRef . current
0 commit comments