Using useDebounce hook with React

Using useDebounce hook with React

Published at


Introduction:

Debouncing is a technique used to limit the rate at which a function can execute, helping to optimize performance and ensure a smooth user experience. It's often employed in web applications to control user-input-based events, such as search-as-you-type or form submission validation. In this blog post, we'll explore the useDebounce custom React hook, which simplifies the process of adding debounce functionality to your components.

Understanding Debouncing:

Debouncing can be thought of as a way to delay the execution of a function until a specified amount of time has passed since the last time it was invoked. By doing so, the function will only execute once during a rapid sequence of events, rather than executing repeatedly with each event. This is particularly useful for situations where a user might be typing quickly in a text input field, for example, as it can prevent unnecessary API calls or UI updates while the user is still typing.

The useDebounce React Hook:

Now, let's take a closer look at the useDebounce custom React hook, which makes it easy to add debounce functionality to your components. The hook takes two parameters: the initial value for the state, and the debounce delay in milliseconds. Here's the code for the hook:

import { useState, useEffect } from "react";

function useDebounceState<T>(value: T, delay: number): [T, T, (value: T) => void] {
  const [currentValue, setCurrentValue] = useState(value);
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    const timeoutId = setTimeout(() => {
      setDebouncedValue(currentValue);
    }, delay);

    return () => {
      clearTimeout(timeoutId);
    };
  }, [currentValue, delay]);

  const setValue = (value: T) => {
    setCurrentValue(value);
  };

  return [currentValue, debouncedValue, setValue];
}

export default useDebounceState;

How it Works:

  1. The hook begins by importing useState and useEffect from the "react" library.
  2. It then defines a generic function, useDebounceState, which accepts a type parameter T, the value of the state, and the debounce delay.
  3. Inside the function, two state variables are created using useState: currentValue and debouncedValue, both initialized with the passed value.
  4. The useEffect hook is used to create a side effect that runs whenever currentValue or delay changes. Inside the effect, a timeout is set with setTimeout to update the debouncedValue with the currentValue after the specified delay. When the effect is cleaned up, the timeout is cleared with clearTimeout to prevent memory leaks and unintended behavior.
  5. The setValue function is created to update the currentValue state, which in turn triggers the debounce effect.
  6. The hook returns an array containing the currentValue, debouncedValue, and the setValue function, providing an easy-to-use API for managing debounce state in your components.

Using the useDebounce Hook:

To demonstrate how you can use the useDebounce hook in your components, let's create a simple example. Imagine you have a search component that needs to fetch results from an API as the user types. By using the useDebounce hook, you can prevent excessive API calls and ensure a smooth user experience:

import React, { useState, useEffect } from "react";
import useDebounceState from "./useDebounceState";

function Search() {
  const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebounceState("", 300);
  const [results, setResults] = useState([]);

  useEffect(() => {
    if (debouncedSearchTerm) {
      fetchResults(debouncedSearchTerm).then((data) => {
        setResults(data);
      });
    } else {
      setResults([]);
    }
  }, [debouncedSearchTerm]);

  const fetchResults = async (term) => {
    // Fetch results from your API using the provided search term
  };

  return (
    <div>
      <input
        type="text"
        placeholder="Search..."
        value={searchTerm}
        onChange={(e) => setSearchTerm(e.target.value)}
      />
      <ul>
        {results.map((result) => (
          <li key={result.id}>{result.name}</li>
        ))}
      </ul>
    </div>
  );
}

export default Search;

In this example, we use the useDebounceState hook to manage the search term, setting the debounce delay to 300 milliseconds. We also use the useState hook to manage the search results. The useEffect hook is used to fetch the search results whenever the debounced search term changes. If the debounced search term is empty, we reset the results to an empty array.

Inside the component's JSX, we render an input field and an unordered list to display the search results. The input field's value is set to searchTerm, and its onChange event handler is set to update the search term using the setSearchTerm function provided by the useDebounceState hook.

Conclusion

In this blog post, we explored the useDebounce custom React hook, which simplifies the process of adding debounce functionality to your components. By using this hook, you can easily debounce user input or other events, helping to optimize performance and provide a smoother user experience. The useDebounce hook is versatile and can be adapted to various use cases, making it a valuable addition to your React toolbox.

Comments

We won't show your email address!

500 characters left