A Shower Of Thoughts

Press F for key shortcuts

In my toolbelt; useDelayedDebounce react hook

Published on

For whenever you need to react to a repeatedly-and-rapidly-fired event, but only some time after the last event occurred.

For example, when you only want to make a request based on the value of a <input type=“text”> but don’t want to send the request every time the user types each character.

useDelayedDebounce.ts #

import { useState, useEffect } from 'react';

/**
* Receives a value that is the result of a repeatedly-and-rapidly-fired event
* and returns the value at the time after the last of those events ocurred.
*
* @param originalValue value to debounce off
* @param delay amount of milliseconds to delay after the last event ocurred
*/

export function useDelayedDebounce<V>(originalValue: V, delay: number): V {
// set the initial debounced value based on the original one,
// and keep it in this hook's state
const [debouncedValue, setDebouncedValue] = useState(originalValue);

// Declare the side-effect that will handle the debouncing.
// Will execute when the component is mounted.
useEffect(
() => {
const handler = setTimeout(() => {
// The debounced value will only be updated after the delay has passed.
setDebouncedValue(originalValue);
}, delay);

// Clean-up. Will execute when the component unmounts.
return () => {
// Cancel the current timeout if it hasn't triggered.
// If the original value changes before the delay time happens,
// then this cancellation will prevent the debounced value from being updated.
clearTimeout(handler);
};
},
// Side-effect will execute when the original value changes
// (which should be "a lot and very quickly" for this whole hook to be useful).
[originalValue]
);

return debouncedValue;
}

Usage Example #

const debouncedTextInput = useDelayedDebounce<string>(textQuery, 500);

// side effect that fetches a thing with the text field's value as input
useEffect(() => {
makeFetch(..., debouncedTextInput, ...);
}, [debouncedTextInput]);

In this usage (contrived) example, the side effect that will make the fetch will run only after 500 milliseconds have passed after the user stopped updating the text field. So no matter how quickly the user is typing, deleting, and otherwise updating the text field value, the request will only be made half a second after the user stopped updating it.



More about: development toolbelt react


← Home