DEV Community

Cover image for Debouncing in React: A Custom Hook Example πŸš€
Vikas Choubey
Vikas Choubey

Posted on

Debouncing in React: A Custom Hook Example πŸš€

This is the part 2 of Designing an autocomplete UI component
Bounce
Debouncing is like that friend who waits for you to finish talking before they chime in with their brilliant ideas. It's all about giving your app a breather, ensuring it doesn't go berserk with every keystroke. In this blog, we're going to have a hilarious look at implementing debouncing in React using a custom hook that we've aptly named "useDebouncedValue." πŸ€ͺ

Understanding Debouncing πŸ€”

Before we dive into the code (cue the drumroll πŸ₯), let's wrap our heads around this concept. Debouncing is the art of delaying the execution of a function until a certain amount of time has passed since the last event. Why? Well, because we don't want our app to freak out and do a gazillion things per second. That would be pure chaos! πŸ™ƒ

The Custom Hook: useDebouncedValue 🎣

hook
Let's not keep you in suspense any longer. Here's our superhero custom hook: useDebouncedValue. It takes an initial value and a delay as parameters, and it returns a debounced value that only updates when the user stops typing for the specified delay period. Ta-da! πŸ¦Έβ€β™‚οΈ

import { useEffect, useState } from "react";
import { DEFAULT_DELAY } from "../constants";

const useDebouncedValue = (
  value = "",
  delay = DEFAULT_DELAY
): string | number => {
  const [debouncedValue, setDebouncedValue] = useState(value);

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

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

  return debouncedValue;
};

export default useDebouncedValue;
Enter fullscreen mode Exit fullscreen mode

Using the Custom Hook: DebounceExample Component πŸŽ‰

Now, let's introduce you to the DebounceExample component which shows us how to use the our star custom hook, DebouncedValue. This component allows you to set a delay and input a value. The debounced value is displayed after the magic of debouncing has worked its charm. πŸͺ„βœ¨

import * as React from "react";
import { DEFAULT_DELAY } from "./constants";
import useDebouncedValue from "./hooks/useDebouncedValue";
import "./style.css";

export default function DebounceExample() {
  const [value, setValue] = React.useState("");
  const [delay, setDelay] = React.useState(DEFAULT_DELAY);
  const debouncedValue = useDebouncedValue(value, delay);

  return (
    <span>
      <h4>Debouncing Example πŸ˜„</h4>
      <hr />
      <div>
        <label htmlFor="delay">Delay:</label>
        <input
          name="delay"
          type="number"
          min="0"
          step="100"
          value={delay}
          onChange={(e) => setDelay(parseInt(e.target.value))}
        />
        ms
      </div>
      <div>
        <label htmlFor="value">Type in:</label>
        <input
          name="value"
          onChange={(e) => setValue(e.target.value)}
          placeholder="debounce πŸ€“"
        />
      </div>
      <div
        style={{
          border: "2px solid grey",
          height: "20px",
          padding: "10px",
        }}
      >
        <span>You have typed: πŸ“</span>
        <span style={{ fontWeight: "700" }}>{debouncedValue}</span>
      </div>
    </span>
  );
}
Enter fullscreen mode Exit fullscreen mode

How It Works πŸ› 

Gears
useDebouncedValue is our secret sauce. We use it within the DebounceExample component to create a debounced value based on the user's input and the specified delay.

Users can adjust the delay value to control how quickly the debounced value updates. It's like being in control of a time machine for your app! πŸ•°οΈ

As users type into the input field, the debounced value stays quiet until the specified delay has passed since the last keystroke. No more app freak-outs; just smooth sailing. β›΅

Practical Usecases of Debouncing in web development

Debouncing is a technique used in web development to control or limit the frequency of certain events, typically user-initiated events like keypresses, mouse movements, and resizing the browser window. It helps to optimize performance and prevent unnecessary or overly frequent event triggers. Here are some common use cases for debouncing in web development:

  1. Input Fields and Search Bars πŸ”: When a user is typing in an input field, you might want to perform an action (like sending an API request for search suggestions) only after they've stopped typing for a brief moment, rather than with every keystroke. Debouncing helps in waiting for a pause in typing.

  2. Resize Events πŸ–₯️: When a user resizes their browser window, this event can fire rapidly. You might use debouncing to trigger an action after the user has finished resizing, preventing excessive re-rendering of the page.

  3. Scroll Events πŸ“œ: Scrolling can generate a large number of scroll events, especially when the user rapidly scrolls. Debouncing helps in triggering actions like lazy-loading images or infinite scrolling after the scrolling activity has settled.

  4. Mousemove Events 🐭: Tracking the mouse's position can generate a lot of events. Debouncing can be useful when you want to update an element's position or appearance based on the mouse position, but only when the mouse has stopped moving.

  5. Button Clicks πŸ–±οΈ: In some cases, you might want to limit how quickly a user can trigger a particular action, such as submitting a form or saving data.

  6. Autosave πŸ’Ύ: In forms and text editors, it's common to implement an autosave feature. Debouncing can be used to trigger an autosave action after the user has stopped typing for a moment, reducing the number of saves and potential server requests.

  7. Infinite Scrolling πŸ”„: When implementing infinite scrolling in a web page, you can use debouncing to control when the next set of data should be loaded as the user approaches the bottom of the page.

  8. Delaying API Requests 🌐: If you need to fetch data from an API based on user input (e.g., searching for products), debouncing can ensure that you only send requests to the server once the user has paused their input.

  9. Validation and Error Checking βœ…βŒ: When validating user input, such as email addresses or passwords, you might want to perform validation after the user has finished typing, rather than after every character input.

  10. Autocomplete and Dropdowns 🌟: Implementing auto-suggestions in search boxes or dropdown menus can benefit from debouncing to prevent unnecessary or rapid updates to the suggestion list.

Debouncing is an essential tool for improving user experience and optimizing performance in web development. It ensures that actions are only taken when they are truly needed, reducing unnecessary processing and preventing "noisy" event handling.

Conclusion 🎊

study
Here's a stackblitz codeflow for you to test Debouncing
Debouncing is the superhero your app needs to maintain peace and order in the chaotic world of rapid user input. By creating a custom hook like useDebouncedValue, you can easily implement debouncing in your React applications, making your UI responsive and ensuring your app doesn't lose its marbles. πŸš€πŸ™Œ

Connect with me on my:

LinkedIn
GitHub
Twitter

Top comments (3)

Collapse
 
dsaga profile image
Dusan Petkovic

Hey Vikas, thanks for the detailed and humorous post, its refreshing to read a new take on the debouncing topic, just one question, I am not seeing where you're clearing the previous timeout, it seams that in the code example above its only getting cleared on unmount, but not on re-renders..?

Also, a heads up, stackblitz link gives me a 404
stackblitz.com/edit/react-ts-csuk9o

Thanks!!
keep it up

Collapse
 
vikas2426 profile image
Vikas Choubey • Edited

Hi Dusan,
if you notice the useEffect is dependent on 'value' and the app rerenders whenever 'value' changes, so that's how timeout is getting cleared on rerenders.
Thanks a million for informing about the link issue, it should be fixed now.

Collapse
 
dsaga profile image
Dusan Petkovic

You're right, thanks, learned something today lol