Debouncing and Throttling in React

Marko Troskot
3 min readApr 17, 2020

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.

FuncUtils.js

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.

Home component before adding debounce

Fairly simple component, below you can see it in action.

fetchData without debounce

Let’s now debounce fecthData function to reduce the number of calls to API endpoint.

Home component after adding debounce

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.

fetchData with debounce

In React function based component we have multiple ways to achieve this.

#1 Using useEffect without the previously written debounce function

Debouncing using hooks

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

Debouncing using hooks and debounce func

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.

Debouncing with custom debounce function

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.

Home component before adding throttle

Again a simple component, below you can see it in action.

logCounter without throttle

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.

logCounter with throttle

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.

Throttling using hooks and throttle function

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! 😃

--

--

Marko Troskot

FE developer • JavaScript • React.js • React Native