1
- import { useCallback , useMemo , useRef } from 'react'
1
+ import { useMemo , useRef } from 'react'
2
2
import useTimeout from './useTimeout'
3
- import useMounted from './useMounted'
4
3
import useEventCallback from './useEventCallback'
4
+ import useWillUnmount from './useWillUnmount'
5
5
6
6
export interface UseDebouncedCallbackOptions {
7
7
wait : number
@@ -55,6 +55,8 @@ function useDebouncedCallback<TCallback extends (...args: any[]) => any>(
55
55
56
56
const isTimerSetRef = useRef ( false )
57
57
const lastArgsRef = useRef < unknown [ ] | null > ( null )
58
+ // Use any to bypass type issue with setTimeout.
59
+ const timerRef = useRef < any > ( 0 )
58
60
59
61
const handleCallback = useEventCallback ( fn )
60
62
@@ -69,6 +71,11 @@ function useDebouncedCallback<TCallback extends (...args: any[]) => any>(
69
71
70
72
const timeout = useTimeout ( )
71
73
74
+ useWillUnmount ( ( ) => {
75
+ clearTimeout ( timerRef . current )
76
+ isTimerSetRef . current = false
77
+ } )
78
+
72
79
return useMemo ( ( ) => {
73
80
const hasMaxWait = ! ! maxWait
74
81
@@ -161,14 +168,14 @@ function useDebouncedCallback<TCallback extends (...args: any[]) => any>(
161
168
if ( hasMaxWait ) {
162
169
// Handle invocations in a tight loop.
163
170
isTimerSetRef . current = true
164
- setTimeout ( timerExpired , wait )
171
+ timerRef . current = setTimeout ( timerExpired , wait )
165
172
return invokeFunc ( lastCallTimeRef . current )
166
173
}
167
174
}
168
175
169
176
if ( ! isTimerSetRef . current ) {
170
177
isTimerSetRef . current = true
171
- setTimeout ( timerExpired , wait )
178
+ timerRef . current = setTimeout ( timerExpired , wait )
172
179
}
173
180
174
181
return returnValueRef . current
0 commit comments