~/swaraj.dev
Back to all posts
March 30, 20261 min read

Debounce API Calls in React Native with a Custom Hook

Prevent excessive network traffic by debouncing input‑driven API calls with a tiny reusable hook.

react nativehooksperformancetypescript

Insight

When users type into a search box, each keystroke can fire a fetch, quickly exhausting rate limits and hurting battery life. Debouncing batches rapid changes into a single request after the user pauses, keeping the UI responsive and the network clean.

Example

import { useState, useEffect, useCallback } from "react";

function useDebounce<T>(value: T, delay = 300): T {
  const [debounced, setDebounced] = useState(value);
  useEffect(() => {
    const id = setTimeout(() => setDebounced(value), delay);
    return () => clearTimeout(id);
  }, [value, delay]);
  return debounced;
}

// Usage in a component
export default function Search() {
  const [query, setQuery] = useState("");
  const debouncedQuery = useDebounce(query);

  const fetchResults = useCallback(async () => {
    if (!debouncedQuery) return;
    const res = await fetch(`https://api.example.com/search?q=${debouncedQuery}`);
    // handle response
  }, [debouncedQuery]);

  useEffect(() => {
    fetchResults();
  }, [fetchResults]);

  return <TextInput value={query} onChangeText={setQuery} placeholder="Search..." />;
}

Takeaway

Wrap the debounce logic in a hook and reuse it anywhere you need to throttle rapid state changes. Adjust the delay to match your UX expectations, and you’ll see fewer wasted requests and smoother interactions.