DEV Community

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

Posted on

12 1 1 3 1

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

Image of Datadog

How to Diagram Your Cloud Architecture

Cloud architecture diagrams provide critical visibility into the resources in your environment and how theyโ€™re connected. In our latest eBook, AWS Solution Architects Jason Mimick and James Wenzel walk through best practices on how to build effective and professional diagrams.

Download the Free eBook

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

๐Ÿ‘‹ Kindness is contagious

Please leave a โค๏ธ or a friendly comment on this post if you found it helpful!

Okay