This is the part 2 of Designing an autocomplete UI component
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 ðĢ
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;
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>
);
}
How It Works ð
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:
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.
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.
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.
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.
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.
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.
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.
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.
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.
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 ð
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. ðð
Top comments (3)
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
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.
You're right, thanks, learned something today lol