Ever built a dropdown that lags or freezes your app every time the user types a letter? You probably need a searchable dropdown with debounce, a technique that delays API requests until the user stops typing for a moment.

  • How to set up a fast development environment using React and Vite.
  • What debouncing is and why it saves your REST API from too many requests.
  • How to fetch and display live search results from a public REST API.
  • Common pitfalls like handling race conditions and empty states.

Setting Up the Project and the Search State

First, create a new Vite project and set up a component that holds the user input, the fetched results, and a loading state. We will use the native fetch function to get data from a public REST API.

import { useState, useEffect } from 'react';

export default function SearchDropdown() {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState([]);
  const [isLoading, setIsLoading] = useState(false);

  return (
    
       setQuery(e.target.value)}
        placeholder="Search countries..."
      />
      {isLoading && 

Loading...

}
    {results.map((item) => (
  • {item.name.common}
  • ))}
); }

This basic setup gives us an input field that tracks what the user types and renders an empty list for now.

Adding Debounce to Protect Your REST API

If we fetch data on every single keystroke, the app will make dozens of unnecessary network requests. We use a timer to wait 300 milliseconds after the user stops typing before making the API call.

useEffect(() => {
  if (!query.trim()) {
    setResults([]);
    return;
  }

  setIsLoading(true);
  const timer = setTimeout(async () => {
    try {
      const response = await fetch(`https://restcountries.com/v3.1/name/${query}`);
      const data = await response.json();
      setResults(Array.isArray(data) ? data : []);
    } catch (error) {
      setResults([]);
    } finally {
      setIsLoading(false);
    }
  }, 300);

  return () => clearTimeout(timer);
}, [query]);

The setTimeout function delays our API call, and returning clearTimeout ensures we cancel the previous timer if the user types another letter quickly.

Common mistakes

A frequent mistake is forgetting to clear the results array when the user deletes their search input, leaving old items on the screen. Another issue is ignoring race conditions where a slow network response from an older search overwrites a newer search result.

Try adding keyboard navigation next so users can use the arrow keys to select items from your new searchable dropdown.