useDebounceFn
Debounces a callback and reports whether its timeout window is active.
About
useDebounceFn returns a callback that can run on the leading edge, trailing edge, or both, along with a boolean indicating an active debounce window.
Examples
import { useState } from "react";
import { useDebounceFn } from "rooks";
export default function DebouncedSave() {
const [status, setStatus] = useState("Idle");
const [save, pending] = useDebounceFn(
(...args: unknown[]) => setStatus(`Saved ${String(args[0] ?? "draft")}`),
400,
{ leading: false, trailing: true }
);
return (
<section>
<button type="button" onClick={() => save("draft")}>
Save draft
</button>
<p role="status">{pending ? "Waiting to save" : status}</p>
</section>
);
}Parameters
| Argument | Type | Default | Meaning |
|---|---|---|---|
func | (...args) => unknown | required | Latest callback; its return value is discarded. |
delay | number | required | Trailing delay in milliseconds. |
options.leading | boolean | false when options are omitted | Invoke immediately when a window opens. |
options.trailing | boolean | true when options are omitted | Invoke with latest arguments after the delay. |
options.maxWait | number | undefined | Bounds delay during repeated calls; must be at least delay. |
Passing both edges as false throws. Passing an explicit {} also throws because defaults apply to the whole omitted object, not to missing properties. For leading-only behavior, note that without a trailing timer or maxWait, the current implementation leaves its timeout flag enabled after the first invocation.
Return value
[debouncedFunction, isTimeoutEnabled]. The stable wrapper accepts the original parameters and returns void. The boolean is true while the hook considers a debounce window active.
Behavior and lifecycle
Trailing execution uses the latest arguments and callback. Leading plus trailing can invoke once immediately and again at the end even for one call. Repeated calls reset the delay; maxWait adds a second bound. Timer cleanup follows useTimeoutWhen on dependency changes and unmount. Synchronous callback errors are caught and sent to console.warn rather than thrown to the caller.
Compatibility and accessibility
Browser timeouts are created only after effects run, so no timer is scheduled in server HTML. Delayed actions need visible status, and buttons should not be disabled solely from a stale visual assumption; use the returned boolean intentionally.