Aur UI

Use Debounced Value

Returns a value only after it stops changing — the search-as-you-type companion.

bash
pnpm add @aur-ui/ui
tsx
import { useDebouncedValue } from "@aur-ui/ui/hooks/use-debounced-value";

function ProjectSearch() {
  const [query, setQuery] = useState("");
  const debouncedQuery = useDebouncedValue(query, 300);

  const { data } = useProjects({ query: debouncedQuery });

  return <SearchField value={query} onValueChange={setQuery} />;
}

Keep the input controlled by the raw value and drive the query or filter from the debounced one. The delay defaults to 300ms; the pending timer is cleared on every change and on unmount, so only the settled value ever lands.

hooks/use-debounced-value.ts
"use client";

import { useEffect, useState } from "react";

/**
 * Returns `value` after it has stayed unchanged for `delay` ms. The classic
 * search-as-you-type companion: keep the input controlled by the raw value,
 * drive the query/filter from the debounced one.
 *
 * The pending timer is cleared on every change and on unmount, so only the
 * settled value ever lands. `delay` defaults to 300ms.
 */
export function useDebouncedValue<T>(value: T, delay = 300): T {
  const [debounced, setDebounced] = useState(value);

  useEffect(() => {
    const timer = setTimeout(() => setDebounced(value), delay);
    return () => clearTimeout(timer);
  }, [value, delay]);

  return debounced;
}