How to Use Debounce with useQuery in React Query?

Learn how to use debounce with useQuery in React Query to fetch filtered data based on user input without triggering excessive network requests.

|

Instead of debouncing the fetch function directly, you should debounce the query parameters (e.g., the search value) so that the queryKey changes only after a delay. This way useQuery is called only when the input has stabilized, not on every keystroke.

1. Create a useDebounce Hook

This hook will delay the value and only set the debounced value after the specified delay:

function useDebounce(value, delay) {  const [debouncedValue, setDebouncedValue] = useState(value);  useEffect(() => {

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

    return () => clearTimeout(handler);

  }, [value, delay]);

  return debouncedValue;

}

2. Use Debounced Value in Your Query Component

Now use useDebounce with useQuery like this:

const debouncedSearch = useDebounce(search, 500);

const { data, isLoading, isError } = useQuery({

  queryKey: [‘todos’, page, debouncedSearch],

  queryFn: () => fetch(`/api/todos?page=${page}&q=${debouncedSearch}`)

               .then(res => res.json()),

  enabled: !!debouncedSearch,

});

This way the query will only run after the debounced value changes

Also ReadHow Much Does It Cost to Hire Remote React Developers?

Why This Works

  • Debouncing the queryKey instead of the query function matches React Query’s caching and lifecycle logic.
  • useQuery will only trigger when debouncedSearch changes, not on every keystroke.
  • You still get all the benefits of caching, isLoading, isError and other React Query states
Related

Why am I getting this problem? By default, Material React Table renders plain text for each cell based on your data accessor. If you supply…

28 Jan 2026

You can’t set CORS response headers from React (client-side). Browsers enforce CORS based on the server, so you must configure your API server or use…

19 Jan 2026

Why am I getting this problem? If you apply separate filters in sequence or only check one property at a time your code will match…

20 Jan 2026