UNPKG

4.5 kBTypeScriptView Raw
1export interface CallOptions {
2 /**
3 * Controls if the function should be invoked on the leading edge of the timeout.
4 */
5 leading?: boolean;
6 /**
7 * Controls if the function should be invoked on the trailing edge of the timeout.
8 */
9 trailing?: boolean;
10}
11export interface Options extends CallOptions {
12 /**
13 * The maximum time the given function is allowed to be delayed before it's invoked.
14 */
15 maxWait?: number;
16 /**
17 * If the setting is set to true, all debouncing and timers will happen on the server side as well
18 */
19 debounceOnServer?: boolean;
20}
21export interface ControlFunctions<ReturnT> {
22 /**
23 * Cancel pending function invocations
24 */
25 cancel: () => void;
26 /**
27 * Immediately invoke pending function invocations
28 */
29 flush: () => ReturnT | undefined;
30 /**
31 * Returns `true` if there are any pending function invocations
32 */
33 isPending: () => boolean;
34}
35/**
36 * Subsequent calls to the debounced function return the result of the last func invocation.
37 * Note, that if there are no previous invocations you will get undefined. You should check it in your code properly.
38 */
39export interface DebouncedState<T extends (...args: any) => ReturnType<T>> extends ControlFunctions<ReturnType<T>> {
40 (...args: Parameters<T>): ReturnType<T> | undefined;
41}
42/**
43 * Creates a debounced function that delays invoking `func` until after `wait`
44 * milliseconds have elapsed since the last time the debounced function was
45 * invoked, or until the next browser frame is drawn.
46 *
47 * The debounced function comes with a `cancel` method to cancel delayed `func`
48 * invocations and a `flush` method to immediately invoke them.
49 *
50 * Provide `options` to indicate whether `func` should be invoked on the leading
51 * and/or trailing edge of the `wait` timeout. The `func` is invoked with the
52 * last arguments provided to the debounced function.
53 *
54 * Subsequent calls to the debounced function return the result of the last
55 * `func` invocation.
56 *
57 * **Note:** If `leading` and `trailing` options are `true`, `func` is
58 * invoked on the trailing edge of the timeout only if the debounced function
59 * is invoked more than once during the `wait` timeout.
60 *
61 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
62 * until the next tick, similar to `setTimeout` with a timeout of `0`.
63 *
64 * If `wait` is omitted in an environment with `requestAnimationFrame`, `func`
65 * invocation will be deferred until the next frame is drawn (typically about
66 * 16ms).
67 *
68 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
69 * for details over the differences between `debounce` and `throttle`.
70 *
71 * @category Function
72 * @param {Function} func The function to debounce.
73 * @param {number} [wait=0]
74 * The number of milliseconds to delay; if omitted, `requestAnimationFrame` is
75 * used (if available, otherwise it will be setTimeout(...,0)).
76 * @param {Object} [options={}] The options object.
77 * Controls if `func` should be invoked on the leading edge of the timeout.
78 * @param {boolean} [options.leading=false]
79 * The maximum time `func` is allowed to be delayed before it's invoked.
80 * @param {number} [options.maxWait]
81 * Controls if `func` should be invoked the trailing edge of the timeout.
82 * @param {boolean} [options.trailing=true]
83 * @returns {Function} Returns the new debounced function.
84 * @example
85 *
86 * // Avoid costly calculations while the window size is in flux.
87 * const resizeHandler = useDebouncedCallback(calculateLayout, 150);
88 * window.addEventListener('resize', resizeHandler)
89 *
90 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
91 * const clickHandler = useDebouncedCallback(sendMail, 300, {
92 * leading: true,
93 * trailing: false,
94 * })
95 * <button onClick={clickHandler}>click me</button>
96 *
97 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
98 * const debounced = useDebouncedCallback(batchLog, 250, { 'maxWait': 1000 })
99 * const source = new EventSource('/stream')
100 * source.addEventListener('message', debounced)
101 *
102 * // Cancel the trailing debounced invocation.
103 * window.addEventListener('popstate', debounced.cancel)
104 *
105 * // Check for pending invocations.
106 * const status = debounced.pending() ? "Pending..." : "Ready"
107 */
108export default function useDebouncedCallback<T extends (...args: any) => ReturnType<T>>(func: T, wait?: number, options?: Options): DebouncedState<T>;