The Perfect React useDebounce Hook for API Calls

If you are building search bars, auto-complete inputs, or real-time filters, firing an API request to your database on every single keystroke is a great way to crash your server and ruin your performance.

You need to “debounce” the input so the request only fires after the user pauses their typing. Here is a clean, dependency-free custom React hook that handles this flawlessly.

import { useState, useEffect } from 'react';

export function useDebounce(value, delay) {
  // State and setters for debounced value
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    // Update debounced value after delay
    const handler = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);

    // Cancel the timeout if value changes (also on delay change or unmount)
    // This is how we prevent debounced value from updating if value is changed ...
    // .. within the delay period. Timeout gets cleared and restarted.
    return () => {
      clearTimeout(handler);
    };
  }, [value, delay]); // Only re-call effect if value or delay changes

  return debouncedValue;
}

How to Use It

Simply pass your search input state and your desired delay (in milliseconds) into the hook. Use the returned debounced value inside your useEffect to trigger your fetch requests.

// Example Usage
const [searchTerm, setSearchTerm] = useState('');
const debouncedSearchTerm = useDebounce(searchTerm, 500);

useEffect(() => {
  if (debouncedSearchTerm) {
    // Fire your API call here!
    fetchResults(debouncedSearchTerm);
  }
}, [debouncedSearchTerm]);

Leave a Comment