react useDebounce

A simple debounce hook for React applications. Useful for when you want to limit the number of times a function is called to improve performance
Saturday, February 24, 2024

What is debounce?

Debouncing is a programming practice used to ensure that certain events do not fire too often, this could be anything from a button click to a search input. The idea is to limit the number of times a function is called to improve performance and prevent unnecessary re-renders.

Most commonly, debounce is used in the context of user input, such as a search input. When a user types into a search input, the application will often make a request to a server to fetch the results. If the user types quickly, this could result in a large number of requests being made in a short period of time. By debouncing the input, we can ensure that the request is only made after the user has stopped typing for a certain period of time.

A simple debounce hook

Here’s a simple debounce hook that you can use in your React applications:

import { useState, useEffect } from 'react';

/**
 * useDebounce hook
 * 
 * @param {any} value The value to debounce.
 * @param {number} delay The delay in milliseconds to wait before updating the debounced value.
 * @return The debounced value.
 */
function useDebounce(value, delay) {
  // State and setters for debounced value
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    // Set debouncedValue to value (passed in) after the specified delay
    const handler = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);

    // Cancel the timeout if value changes (also on component unmount), which is the cleanup function of useEffect
    return () => {
      clearTimeout(handler);
    };
  }, [value, delay]); // Only re-call effect if value or delay changes

  return debouncedValue;
}

export default useDebounce;

You can use this hook in your components like this:

import React, { useState } from 'react';
import useDebounce from './useDebounce';

function MyComponent() {
  // State and setter for search term
  const [searchTerm, setSearchTerm] = useState('');

  // State and setter for search results
  const [results, setResults] = useState([]);

  // Now we call our hook, passing in the current searchTerm value and the delay
  // we'd like to wait before updating the debounced value
  const debouncedSearchTerm = useDebounce(searchTerm, 500);

  useEffect(
    () => {
      if (debouncedSearchTerm) {
        searchCharacters(debouncedSearchTerm).then(results => {
          setResults(results);
        });
      }
    },
    [debouncedSearchTerm] // Only call effect if debounced search term changes
  );
}

In this example, we have a search input that updates the searchTerm state as the user types. We then use the useDebounce hook to debounce the searchTerm value, and only make the request to the server after the user has stopped typing for 500 milliseconds.

This way we don’t send too many unnecessary requests to the server, but instead for the most part only send a request when the user has stopped typing for a desired amount of time, in this case half a second.

To lean more about hooks and how to use them check out my article on React Hooks

Wanna show support?

If you find my sporadic thoughts and ramblings helpful.
You can buy me a coffee if you feel like it.
It's not necessary but it's always appreciated. The content will always stay free regardless.