Rooks
HooksPerformance & Optimization

useDebounce

Returns a stable Lodash-style debounced wrapper around the latest callback.

About

useDebounce groups calls made close together and invokes the latest callback at the configured edge of the wait window. The returned function also exposes cancel() and flush().

Examples

import { useState } from "react";
import { useDebounce } from "rooks";

export default function DebouncedInput() {
  const [draft, setDraft] = useState("");
  const [saved, setSaved] = useState("");
  const save = useDebounce((value: string) => setSaved(value), 400);

  return (
    <label>
      Draft
      <input
        value={draft}
        onChange={(event) => {
          setDraft(event.target.value);
          save(event.target.value);
        }}
      />
      <span>Saved: {saved}</span>
      <button type="button" onClick={() => save.flush()}>
        Save now
      </button>
    </label>
  );
}

Parameters

ArgumentTypeDefaultMeaning
callback(...args) => unknownrequiredLatest function invoked by the wrapper.
waitnumberLodash default (0)Delay in milliseconds.
options.leadingbooleanfalseInvoke at the start of a burst.
options.trailingbooleantrueInvoke at the end of a burst.
options.maxWaitnumberundefinedMaximum delay while calls keep arriving.

The settings shape is not exported from the package root.

Return value

A stable debounced function with the callback's parameters, plus cancel(): void and flush(). Calling cancel drops pending work; flush immediately runs a pending trailing call. The internal wrapper does not forward the callback's runtime return value, so use side effects rather than relying on a result.

Behavior and lifecycle

Repeated trailing calls use the latest arguments and latest callback. Pending work is cancelled on unmount. The debounced function is created only on the first render, so later wait or options changes do not reconfigure it; remount or keep those values constant. Exceptions propagate when the callback actually runs.

Compatibility and accessibility

The implementation uses timers and does not require the DOM. Effects still do not run during server rendering. For debounced search or validation, keep labels and errors associated with their controls and announce important delayed results without flooding a live region.

On this page