Understanding Debounce by building an awesome search filter in NEXT JS

thumbnail

Hello friends, today in this post we will understand one of the important concepts of Javascript Debounceby creating a search filter using NEXT JS. I have implemented a search filter for my blog posts on our CodeWithMarish website using debounce concept. Let's get started by understanding what Debounce means.

Debouncing is one of the best practices followed when we have a time-consuming function and we want to limit the number of execution. Since javascript is a single-threaded function if we run these heavy functions then it will slow down our app and negatively impact the application performance. So Debouncing will delay the function execution and executing only after a delay. Let's get started with the implementation.

You can follow the below steps in implementing this search feature in your existing app or you can create a new project using

npm create-next-app search-filter-demo

Let's create a new folder components and inside that create a Search component with the props as filtered data and onchange function to update search text in the parent component. Inside return, we will have a text input and return component based on the filtered results.

/components/Search.jsx

import React from "react";

const Search = ({ filteredData, handleChange }) => {
  return (
    <div className="search">
      <input
        type={"text"}
        placeholder="Search..."
        onChange={(e) => handleChange(e.target.value)}
      />
      <div className="search-results">
        {filteredData.isSearch && !filteredData.resultFound && (
          <p>No results found..</p>
        )}
        {filteredData.data.map((data) => {
          return (
            <a className="data" key={data} target="_blank">
              <p>{data}</p>
            </a>
          );
        })}
      </div>
    </div>
  );
};

export default Search;

In index.js we will create a debounce function which is a higher-order function(that accepts a function as an argument and returns another function). Ths debounce function will have two arguments, a function, and a wait parameter. Declare a timerId which we will then assign to setTimeout. Now on the return, we will have a function with args as a parameter, after that we will assign timerId to setTimeout which requires a function for that we will call the function which we passed in and the number of milliseconds to wait for the timeout function to execute.

/pages/index.js

...
const debounce = (func, wait) => {
    let timerId;
    return (...args) => {
      if (timerId) clearTimeout(timerId);
      timerId = setTimeout(() => {
        func(...args);
      }, wait);
    };
  };
...

Now we will have a state variable for the search of type string and filteredData of type Object which includes post(empty list), isSearch(boolean false), resultFound(boolean false). For the filter function, we will use the filter method and use indexOf method for comparison. Also, we will filter only if the search value is not empty, and this filter function will be called whenever the search value is updated using useEffect.

Let’s import this Search component into our index.js and for the input change prop we will call this debounce function and pass the filter function and wait parameter value greater than 0 (1000 = 1sec), so we will give 2000 as of now, and will change it as per our requirements, and also pass the filteredData state variable to this component.

/pages/index.js

import { useState, useEffect } from "react";
import Search from "../components/Search";
const data = [
  "Create a NEWS App using Next JS and React Query",
  "Regular Expression (Regex) Essentials for Developers",
  "How to create a contact form in Next JS and Firebase?",
  "Build PWA (Progressive Web App) with Next JS under 1 minute",
  "Important Meta Tags that you should have on your website",
  "How to create a responsive navbar in NEXT JS?",
  "Create a Tic Tac Toe Game using NEXT JS",
  "How to add push notification in a Next/React JS App?",
  "Newsletter Subscription using NEXT JS and Mailchimp API",
];
export default function Home() {
  const [search, setSearch] = useState("");
  const [filteredData, setFilteredData] = useState({
    data: [],
    isSearch: false,
    resultFound: false,
  });
const debounce = (func, wait) => {
    let timerId;
    return (...args) => {
      if (timerId) clearTimeout(timerId);
      timerId = setTimeout(() => {
        func(...args);
      }, wait);
    };
  };
const filterData = () => {
    let fData = [];
    let resultFound = false;
    if (search) {
      fData = [...data.filter((d) => d.toLowerCase().indexOf(search) != -1)];
      if (fData.length > 0) {
        resultFound = true;
      }
    }
    setFilteredData({
      ...fData,
      data: [...fData],
      isSearch: search.trim().length > 0,
      resultFound: resultFound,
    });
  };
  useEffect(() => {
    filterData();
  }, [search]);
  return (
    <div className="container">
      <Search
        handleChange={debounce((v) => {
          setSearch(v);
        }, 2000)}
        filteredData={filteredData}
      />
    </div>
  );
}

Add some styles to the components.

*{
  padding: 0;
  margin: 0;
  box-sizing: border-box;

  font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
    Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}

a {
  color: inherit;
  text-decoration: none;
}
body{
  background-color: #ddd;
}
.container{
  width: 100%;
  max-width: 300px;
  margin: 25vh auto 0px;
  min-height: 100vh;

}


input{
  padding: 4px;
  width: 100%;
  border: none;
  outline: none;
  font-size: 16px;
  border: 1px solid #eee;
  border-radius: 4px;
}

.search-results{
  font-size: 16px;
  background-color: white;
}

.data p{
  padding: 4px;
}

Now, run your app using 'npm run dev' or 'yarn dev' and search you will be able to see suggestions if not results then you will see no results found text. You can see the live demo on our website homepage by searching for a post.

https://codewithmarish.com/

Thanks for reading this post, if you found this post helpful please share maximum, Thanks for reading 😊 Stay tuned.

You can find the code repository on Github

https://github.com/CodeWithMarish/search-filter-demo

If you are facing any issues please contact us from our contact section.

Contact Us | CodeWithMarish

Also please don’t forget to subscribe to our youtube channel codewithmarish for all web development-related challenges.

Code With Marish | Youtube

Related Posts