Ever built a dropdown that lags every time you type a letter because it fetches data too fast? Let's fix that by building a searchable dropdown with built-in debouncing.

  • How to use TypeScript interfaces to type your dropdown options
  • Implementing a debounce hook to delay search API calls
  • Styling a clean dropdown overlay with Tailwind CSS
  • Managing keyboard navigation and click-away listeners

Setting Up the TypeScript Types

Before writing any UI code, we need to define the shape of our data. TypeScript helps us catch bugs early by ensuring our component receives the correct props.

export interface Option {
  id: string | number;
  label: string;
}

interface SearchableDropdownProps {
  options: Option[];
  value: Option | null;
  onChange: (option: Option) => void;
  isLoading?: boolean;
  onSearch: (query: string) => void;
}

Defining these interfaces upfront makes the rest of our component much easier to reason about.

TypeScript development Photo by Ilya Pavlov on Unsplash

Adding the Debounce Logic

A debounce function delays executing our search until the user stops typing for a specific number of milliseconds. This prevents your app from sending a network request on every single keystroke.

import { useState, useEffect } from 'react';

export function useDebounce<T>(value: T, delay: number): T {
  const [debouncedValue, setDebouncedValue] = useState<T>(value);

  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);

    return () => {
      clearTimeout(handler);
    };
  }, [value, delay]);

  return debouncedValue;
}

The cleanup function using clearTimeout is essential here to clear the previous timer every time the user types a new letter.

Common mistakes

A common mistake is forgetting to clear your timeout inside the useEffect cleanup function, which can lead to memory leaks and unexpected state updates. Another trap is failing to handle keyboard accessibility, making the dropdown impossible to use for people who rely on screen readers or keyboard navigation.

Try adding keyboard arrow key support to your new dropdown so users can select items without touching the mouse.