Debouncing and Throttling in React
How to implement debouncing
and throttling
in React without using any 3rd part library? In this article I’ll show you how this can be done in React class based components and function based components.
Quick intro
Debouncing enforces that a function won’t be called again until a certain amount of time has passed without it being called.
Throttling enforces a maximum number of times a function can be called over time.
Let’s see how that works in action.
Debounce and Throttle functions
Without using any 3rd part libraries we need first to create our debounce and throttle functions.
I won’t go into details about the functions above, I assume that you are familiar with setTimeout in JavaScript.
Debouncing
In this example we have a text input which on every input calls a fecthData
function for fetching data from API endpoint. We want to debounce the fecthData
function so that it is only called after 1 second from users last input.
First I will show you how the React class based component looks like before debouncing fecthData
.
Fairly simple component, below you can see it in action.
Let’s now debounce fecthData
function to reduce the number of calls to API endpoint.
The constructor is where the magic happens.
this.debouncedFetch = debounce(this.fetchData, 1000);
We are calling the debounce function with the function we want to debounce and the delay in miliseconds. All we have to do now is in our handler method to call this.debouncedFetch
instead of this.fecthData
. Let’s see that in action.
In React function based component we have multiple ways to achieve this.
#1 Using useEffect without the previously written debounce function
The cleanUp function in useEffect does the trick here. On the first input only setTimeout function is called, after that every time first the cleanUp function is called, which clears the previous timout, and after that setTimeout is called.
#2 Using useEffect with the previously written debounce function
This one is a little bit trickier because on every re-render our debouncedFetch
would get a new value. Here comes useRef to the rescue. With useRef our debouncedFetch
reference doesn’t change during re-renders.
#3 Directly in handler function
export const debounceFunc = (func, handler, delay) => {
clearTimeout(handler);
return setTimeout(func, delay);
};
This modified debounce function takes the timeout handler explicitly as a parameter which ensures that we are clearing the previous timeout.
Throttling
In this example we have a button which on every click increments a counter and logs current counter value. We want to throttle the logCounter
function so that it is called maximum 1 time in a second.
First I will show you how the React class based component looks like before throttling logCounter
.
Again a simple component, below you can see it in action.
Let’s now throttle logCounter
function to reduce it’s number of calls.
Same as in the debounce example, in the constructor we create the function we want to throttle.
this.throttledLog = throttle(this.logCounter, 1000);
In our handler method,instead of calling this.logCounter
,we call this.throttledLog
. Let’s see it in action.
For React function based component you can use the same code as in the debounce example. I’ll just show here #2 approach from above.
If you found this useful, please help by tapping the 👏 button as many times as you’d like so others can find it too. Thank you! 😃