Open Hooks
State Management

useDebounce

Delay value until after a specified delay period to optimize performance and reduce API calls.

useDebounce

Delay value updates until after a specified delay period to optimize performance and reduce unnecessary API calls.

Status: stable
Version: 1.2.0
Bundle Size: ~0.6kb
Requires: React 16.8+

    Installation

    npx open-hook add useDebounce
    yarn dlx open-hook add useDebounce
    pnpm dlx open-hook add useDebounce

    API Reference

    Parameters

    PropTypeDefault
    options?
    number | DebounceOptions
    500
    value?
    T
    -

    DebounceOptions

    PropTypeDefault
    maxWait?
    number
    -
    trailing?
    boolean
    true
    leading?
    boolean
    false
    unit?
    TimeUnit
    'ms'
    delay?
    number
    -

    Returns

    PropTypeDefault
    debouncedValue?
    T
    -

    TypeScript Signature

    type TimeUnit = "ms" | "s" | "min";
    
    interface DebounceOptions {
      delay: number;
      unit?: TimeUnit;
      leading?: boolean;
      trailing?: boolean;
      maxWait?: number;
    }
    
    function useDebounce<T>(value: T, options?: number | DebounceOptions): T;

    Advanced Usage Examples

    // Basic usage with milliseconds
    const debouncedValue = useDebounce(searchTerm, 300);
    // Using different time units
    const debouncedValue = useDebounce(value, {
      delay: 1,
      unit: "s", // 1 second
    });
    
    const debouncedValue2 = useDebounce(value, {
      delay: 2,
      unit: "min", // 2 minutes
    });
    // Trigger immediately on first change
    const debouncedValue = useDebounce(searchTerm, {
      delay: 300,
      leading: true, // Immediate first trigger
      trailing: true, // Also trigger after delay
    });
    // Force update after maximum wait time
    const debouncedValue = useDebounce(value, {
      delay: 500,
      maxWait: 2000, // Force update after 2 seconds max
    });

    Best Practices

    Choose appropriate delay values and configurations based on your use case:

    // Search input - fast feedback with leading edge
    const debouncedSearch = useDebounce(searchTerm, {
      delay: 300,
      leading: true,
      trailing: true,
    });
    
    // Form validation - moderate delay, trailing only
    const debouncedInput = useDebounce(inputValue, {
      delay: 500,
      trailing: true,
    });
    
    // Auto-save with maximum wait time
    const debouncedData = useDebounce(formData, {
      delay: 800,
      maxWait: 5000, // Force save after 5 seconds
    });

    Advanced Features

    • 🚀 Time Units: Use seconds or minutes for longer delays instead of calculating milliseconds
    • ⚡ Leading Edge: Get immediate feedback on first interaction
    • ⏱️ Max Wait: Ensure updates don't get delayed indefinitely
    • 🎯 Trailing Edge: Standard debounce behavior (default)

    Do's and Don'ts

    • ✅ Use leading edge for immediate user feedback
    • ✅ Set maxWait for auto-save functionality
    • ✅ Choose appropriate time units for readability
    • ✅ Use simple number for basic debouncing
    • ❌ Don't use excessively long delays (>5min)
    • ❌ Avoid both leading and trailing false
    • ❌ Don't use complex configs for simple cases

    Performance Metrics

    MetricValueDescription
    Bundle Size~0.6kbMinified + gzipped
    API Calls ReducedUp to 90%Fewer unnecessary requests
    MemoryMinimalSingle timer per instance
    CPU ImpactVery LowSimple setTimeout operation

    Browser Compatibility

    BrowserSupportedNotes
    Chrome (latest)YesFull support
    Firefox (latest)YesFull support
    Safari (latest)YesFull support
    Edge (latest)YesFull support
    IE 11NoNot supported
    Node.jsYesFor SSR environments

    Use Cases

    Search Functionality

    Delay search API calls until the user stops typing to improve performance.

    Auto-save Features

    Automatically save form data after the user pauses editing.

    Form Validation

    Delay expensive validation checks until input stabilizes.

    Filter Operations

    Reduce heavy filtering operations on large datasets.

    Accessibility

    Accessibility Considerations

    • The hook doesn't affect accessibility directly - Ensure loading states are communicated to screen readers - Consider providing immediate feedback for user interactions - Use appropriate ARIA labels for search inputs using debounced values

    Troubleshooting

    Internals

    How It Works

    The hook maintains an internal state for the debounced value and uses setTimeout to delay updates. Each time the input value changes, it clears the previous timer and sets a new one. Only when the timer completes without interruption does it update the debounced value.

    This pattern effectively "debounces" rapid changes, ensuring that expensive operations (like API calls) only happen after the user has stopped providing input for the specified delay period.

    Testing Example

    import { renderHook, act } from "@testing-library/react";
    import { useDebounce } from "./useDebounce";
    
    jest.useFakeTimers();
    
    it("debounces value updates", () => {
      const { result, rerender } = renderHook(
        ({ value, delay }) => useDebounce(value, delay),
        { initialProps: { value: "initial", delay: 500 } }
      );
    
      expect(result.current).toBe("initial");
    
      // Update value
      rerender({ value: "updated", delay: 500 });
      expect(result.current).toBe("initial"); // Still old value
    
      // Fast forward time
      act(() => {
        jest.advanceTimersByTime(500);
      });
    
      expect(result.current).toBe("updated"); // Now updated
    });

    FAQ

    Changelog

    • 2.0.0 — Major release with advanced features
      • Added support for multiple time units (ms, s, min)
      • Implemented leading edge execution option
      • Added trailing edge configuration
      • Introduced maxWait option for forced updates
      • Enhanced TypeScript support with DebounceOptions interface
      • Breaking: Changed API to accept options object
      • Improved memory management with proper cleanup
    • 1.2.0 — Added TypeScript generics and improved performance
    • 1.1.0 — Added configurable delay parameter
    • 1.0.0 — Initial release with basic debounce functionality