Create a Debounce Hook for Search Box Auto-Completion
Tags: javascript, react, beginners, webdev
Published: 2022-01-31 03:59:00

It is common that we have to implement a search function for the items on a website. Auto-completion is a great feature to improve the searching experience of users. 

We know that we can utilize useEffect hook from React to make the fetch API call whenever the input to our search box changes. However, the API call will be fired whenever user types a single character. This might cause some performance issue when the data sets to be searched are growing larger, or if users are having slow internet connection. In order to prevent hitting the API endpoints such frequent, we could implement a debounce function for our auto-complete feature.

Debounce function for making query is a way to slow down the process of querying, and will make the request only after a certain amount of time when user stops typing. The idea is to wrap the state that we want to keep track of with this hook, and only setState after waiting for sometime. After that, in the useEffect hook that calls the API, we are going to use this returned state from the hook to make the API call.

This is how the hook looks like:

```javascript
import { useState, useEffect } from 'react';

const useDebounce = (value, timeout = 500) => {
    const [state, setState] = useState(value);

    useEffect(() => {
        const handler = setTimeout(() => setState(value), timeout);

        return () => clearTimeout(handler);
    }, [value, timeout]);

    return state;
}

export default useDebounce;
```
The idea is just to use the passed in value (the query text) as the initial state, and listen for the change of value. Whenever the value changes, useEffect hook of this function will get triggered and try to setState after a certain of time (the setTimeout that we defined). However, if user keeps on typing, the useEffect hook will get triggered again and the cleaning of useEffect (the return statement) will run first to clear the previous timeout handler. This is why the state will only return after user stopped typing.

This is how we can use this hook in the fetch call useEffect hook (I only show the minimal amount of code to demonstrate):

```javascript
import React, { useState, useEffect } from 'react';

const [query, setQuery] = useState("");
const debouncedQuery = useDebounce(query, 500);

useEffect(() => {
            const fetchResults = () => {
                fetch(`https://api.someapi.com/search?q=${debouncedQuery}`)
                .then(result => result.json())
                .then(data => {
                    // parsed the data and set the options
                })
                .catch(err => console.error(err))
            }
            fetchResults();
    }, [debouncedQuery]);
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w0nlh3mv6i06rsm8ex63.gif)

Click on the link to check out the live demo: [Live Demo](https://cat-breedy.vercel.app/)

{% github https://github.com/OhDylan/cat-breedy %}


**Do follow me for more future articles on web design, programming and self-improvement** 😊

[Follow me on Medium](https://dylanoh.medium.com)