How To Create Your Own Debounce Function in React

Debounce in JavaScript

Akhilesh Ojha
JavaScript in Plain English

--

Photo by Kevin Mueller on Unsplash

Today on 5th December 2020, JavaScript celebrates its 25th Birthday and I thought of explaining one of the most important topics a JavaScript Developer should know about, Debounce function.

What is a Debounce function?

The debounce() function forces a function to wait a certain amount of time before running again. The function is built to limit the number of times a function is called.

But how can this be helpful?

To understand this, let’s take an example of an auto-complete or type-ahead. (We will build our own auto-complete in this article).

So, suppose you have an autocomplete, now to show the dropdown options you will have to fire an API on each keystroke. So if I need to search “Medium Articles” in an autocomplete we will trigger around 14 API calls. Is this efficient? Not at all. But then how to solve this issue? This is when Debounce comes to the picture.

With the use of the debounce function, we only trigger an API when there is a time delay provided by a user when typing. If we give a delay of say 300ms and a user takes around the same time or more to type the next letter or word, we trigger an API.

This significantly reduces the number of API calls and makes our code more efficient.

Creating our Project.

Let us first build an auto complete project which calls API on each keystroke and then improve it using our own custom Debounce function. In the end, we will also see how to use the inbuilt Debounce function which is provided to us by lodash.

Backend code

For this, I have created a short backend using node which gives us words according to the query param (“search string”) provided. You can also use some free APIs for the same.

React code

This is just a simple code where we call the API on every key stroke, onChange of our input

Creating our own Debounce Function

Now comes the fun part. We will first build our own debounceFunction.
One thing to keep in mind is that this function should return a function.
Our debounceFunction will take two arguments, first the function which you need to call when there is a delay (in our example the getDropDown function) and second, the delay amount for calling that function. (delay between the two keypress events)
Now instead of calling getDropDown function directly, we wait for the delay time. This can be achieved by using setTimeout()

Now to fix the context of this and to pass on the arguments to our function of getDropDown, we should call getDropDown function with apply.

Now to stop calling our function again and again, we will have to clear the timeout. Our final debounceFunction should look something like this:

So now on our onInputChangeHandler we can call our debounceFunction.

const onInputChangeHandler = (e) => {
const nextValue = e.target.value
setSearchString(nextValue);
const debounceDropdown = debounceFunction(getDropDown , 1000);
debounceDropdown();
}

But will this work now?

The answer to this is NO. Because whenever we are calling onInputChangeHandler we are creating a fresh debounceFunction that is being invoked on every keystroke and since we are calling the fresh debounceFunction every time, we are loosing the reference to the older debounceFunction and that is why it will loose its value.

To fix this, we will need the useCallback hook.

This should solve our problem. We will now call the API once there is a delay of 1 sec.

Debounce using lodash

Now, instead of creating a debounce function from scratch using can also directly use it from the lodash package

To do this first install the package using

npm i --save lodash.debounce

Then we will import it in our App.js

import debounce from 'lodash.debounce';

Now instead of adding our custom function in useCallback you can just use the debounce provided by lodash.

const debounceDropDown = useCallback(debounce((nextValue) => getDropDown(nextValue), 1000), [])

Finally our App.js should look something like this:

Conclusion

We have now learned what Debounce function is and how to create a custom debounce function. There is a similar concept called Throttle. I’ll try to explain what Throttle is and how to implement it in a scenario in my next article.

--

--