Debouncing in React

Table of contents

Think of this scenario:

You navigate to a listing page for books or properties and want to search based using a name. Each time you hit the keyboard, a search request is effected. Say you want to search for the word "court"; each keystroke will send a request to the API, and won't wait for you to finish. Bad UX, right?

In the image, our query shows that each key stroke triggers an API request. This will severely overwhelm our API:

In React, this can be solved using debouncing. When an input is debounced, a delay is set between when a user types into an input and when the input value is updated. Technically, it helps to delay a function. It is not a good practice to fire a request each time a user types into the input. In our case, debouncing will enable us to only fire a request when we finish typing our search word "court" or any other word for that matter.

Solution

When looking up the solution for this problem, I encountered a couple of solutions:

  1. Plain old JavaScript using inbuilt setTimeout.

  2. Use of a library such as lodash. I managed to easily implement the lodash option and it will be the one I am demonstrating.

Lodash option

First, we'll need to have lodash installed as a dependency:

yarn add lodash

This is the general syntax of lodash's debounce:

_.debounce(func, [wait=0], [options={}])

It "creates a debounced function that delays invoking func until after wait milliseconds have elapsed since the last time the debounced function was invoked."

In your component, ensure you import lodash's namespace like so:

import _ from 'lodash';

In my component, I will be passing my onChange values using useState.

  const [name, setName] = useState('');

I am also passing down the name, and setName into my form:

Inside my original component, I will now be able to debounce the setName function, and this through props, is passed down to my onChange function in the form. As shown below, I am passing the function setName inside the debounce, and specifying the duration for the delay as 300 milliseconds.

Now, if we check our query, we'll notice that it only sends a request when one stops typing and the three seconds elapse:

Initially, the query captured "c", "co", "cou", "cour", and "court". Now, as long as the user types the entire keyword within the 300ms window, a request will only be fired when they stop typing.