-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathuseDebouncedValue.ts
48 lines (39 loc) · 1.27 KB
/
useDebouncedValue.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import { useEffect, useDebugValue, useRef } from 'react'
import useDebouncedState from './useDebouncedState.js'
import { UseDebouncedCallbackOptions } from './useDebouncedCallback.js'
const defaultIsEqual = (a: any, b: any) => a === b
export type UseDebouncedValueOptions = UseDebouncedCallbackOptions & {
isEqual?: (a: any, b: any) => boolean
}
/**
* Debounce a value change by a specified number of milliseconds. Useful
* when you want need to trigger a change based on a value change, but want
* to defer changes until the changes reach some level of infrequency.
*
* @param value
* @param waitOrOptions
* @returns
*/
function useDebouncedValue<TValue>(
value: TValue,
waitOrOptions: number | UseDebouncedValueOptions = 500,
): TValue {
const previousValueRef = useRef<TValue | null>(value)
const isEqual =
typeof waitOrOptions === 'object'
? waitOrOptions.isEqual || defaultIsEqual
: defaultIsEqual
const [debouncedValue, setDebouncedValue] = useDebouncedState(
value,
waitOrOptions,
)
useDebugValue(debouncedValue)
useEffect(() => {
if (!isEqual || !isEqual(previousValueRef.current, value)) {
previousValueRef.current = value
setDebouncedValue(value)
}
})
return debouncedValue
}
export default useDebouncedValue