DEV Community

Michael Gustus
Michael Gustus

Posted on • Edited on

useStateDebounced: debounced state in React

Simple yet powerful solution for debounced state in react. This hook is based on the standard react hook useState. useStateDebounced provides a similar functionality. It returns the same array of [value, setValue] plus debounced value.

useStateDebounced hook

function useStateDebounced(delay, initialState)) {
  const [value, setValue] = useState(initialState);
  const [debouncedValue, setDebouncedValue] = useState(value);

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

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

  return [value, debouncedValue, setValue];
}
Enter fullscreen mode Exit fullscreen mode

Usage

Usually we need debounced state to delay some costly operation execution until user interaction finished. In this example we wait for the user to finish typing in the search dialog before fetching a new list of recipes. So 700 ms after the last user's keystroke debouncedTerm is updated and the server query is executed.

import React, { useEffect, useState } from 'react';
import { useStateDebounced } from 'use-state-debounced';


export const RecipesList = () => {
  const [recipes, setRecipes] = useState([]);
  const [term, debouncedTerm, setTerm] = useStateDebounced(700, 'pizza');

  useEffect(() => {
    const filteredList = await fetchRecepiesFromServer(debouncedTerm);
    setRecipes(filteredList);
  }, [debouncedTerm]);

  return (
    <>
      <input value={term} onChange={e => setTerm(e.target.value)} />

      <ul>
        {recipes.map((r) =>
          (<li key={r.id}>{r.name}</li>)
        )}
      </ul>
    </>
  );
};
Enter fullscreen mode Exit fullscreen mode

In the above example we use <input> as a controlled component. For uncontrolled components the first term parameter can be omitted.

const [, debouncedTerm, setTerm] = useStateDebounced(700);

<input onChange={e => setTerm(e.target.value)} />
Enter fullscreen mode Exit fullscreen mode

TypeScript version of useStateDebounced can be found here.

Top comments (0)