-
Notifications
You must be signed in to change notification settings - Fork 113
/
useThrottledCallback.ts
70 lines (69 loc) · 2.75 KB
/
useThrottledCallback.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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import useDebouncedCallback, {
CallOptions,
DebouncedState,
} from './useDebouncedCallback';
/**
* Creates a throttled function that only invokes `func` at most once per
* every `wait` milliseconds (or once per browser frame).
*
* The throttled function comes with a `cancel` method to cancel delayed `func`
* invocations and a `flush` method to immediately invoke them.
*
* Provide `options` to indicate whether `func` should be invoked on the leading
* and/or trailing edge of the `wait` timeout. The `func` is invoked with the
* last arguments provided to the throttled function.
*
* Subsequent calls to the throttled function return the result of the last
* `func` invocation.
*
* **Note:** If `leading` and `trailing` options are `true`, `func` is
* invoked on the trailing edge of the timeout only if the throttled function
* is invoked more than once during the `wait` timeout.
*
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
* until the next tick, similar to `setTimeout` with a timeout of `0`.
*
* If `wait` is omitted in an environment with `requestAnimationFrame`, `func`
* invocation will be deferred until the next frame is drawn (typically about
* 16ms).
*
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
* for details over the differences between `throttle` and `debounce`.
*
* @category Function
* @param {Function} func The function to throttle.
* @param {number} [wait=0]
* The number of milliseconds to throttle invocations to; if omitted,
* `requestAnimationFrame` is used (if available, otherwise it will be setTimeout(...,0)).
* @param {Object} [options={}] The options object.
* @param {boolean} [options.leading=true]
* Specify invoking on the leading edge of the timeout.
* @param {boolean} [options.trailing=true]
* Specify invoking on the trailing edge of the timeout.
* @returns {Function} Returns the new throttled function.
* @example
*
* // Avoid excessively updating the position while scrolling.
* const scrollHandler = useThrottledCallback(updatePosition, 100)
* window.addEventListener('scroll', scrollHandler)
*
* // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
* const throttled = useThrottledCallback(renewToken, 300000, { 'trailing': false })
* <button onClick={throttled}>click</button>
*
* // Cancel the trailing throttled invocation.
* window.addEventListener('popstate', throttled.cancel);
*/
export default function useThrottledCallback<
T extends (...args: any) => ReturnType<T>,
>(
func: T,
wait: number,
{ leading = true, trailing = true }: CallOptions = {}
): DebouncedState<T> {
return useDebouncedCallback(func, wait, {
maxWait: wait,
leading,
trailing,
});
}