build React Autosuggest from scratch

Easy tutorial to build React Autosuggest from scratch

React Autosuggest or autocomplete component is one of the fundamentally essential UI features which not only enhance your user experience but also provide a simple solution to filter out the exact result that the user is looking for. It is a feature that suggests words or phrases which the User is searching for, from a collection of data.

In this blog, we will try to build an autocomplete/autosuggest component from scratch. Before moving forward you need to have a basic knowledge of React, useState hook, Input and CSS too. I will leave the demo link down so that you can examine the working example.

Getting started

Let’s get started first with installing the required libraries which we going to need for this project, you can use any CSS framework for beautifying the UI.

npx create-react-app autosuggest-component

To keep the tutorial simple and direct, I am going to use only vanilla CSS and install no other component framework.

Also read, How to add/remove input fields dynamically with Reactjs

Structuring Our AutoSuggest Component

In your src folder, open your app.js file and add a title and form input element which takes input from the user, and we will add some CSS to make UI look good,

import "./styles.css";

export default function App() {
  return (
   <div className="App">
    <div className='title'>React Autocomplete/Autosuggest 🚀</div>
    <div className='form-wrapper'>
     <input className='input' type='text' placeholder="search..."/>
    </div>
   </div>
  );
}

and add some CSS to your app.css file,

.App {
  font-family: sans-serif;
  text-align: center;
  background-color: #f2f2f2;
  height:100vh;
}

.title{
  padding-top:80px;
  margin-bottom:30px;
  font-size:25px;
  font-weight:600;
  text-align:center;
}

.form-wrapper{
  position: relative;
  display: inline-block;
  box-shadow: 0px 8px 20px rgb(0 0 0 / 6%);
}


.input{
  width:350px;
  height:45px;
  padding-left:15px;
  border-radius:5px;
  font-size:17px;
  border:none;
}

.input:focus{
  outline:none;
}

So finally our component UI will look something like this,

React Autosuggest

Also read, React DevTools

Defining Methods and adding Functionality

Before moving forward we need to add a collection of data through which the User will search, for example, I am going to use different country’s names, and users will input a country’s name and it will suggest countries that match the user’s input letters one by one. So I will create a file named fakeData.js and store all the countries’ names.

export const countries = [
  { id: 1, game:'China' },
  { id: 2, game:'India' },
  { id: 3, game:'United States' },
  { id: 4, game:'Indonesia' },
  { id: 5, game:'Pakistan' },
  { id: 6, game:'Brazil' },
  { id: 7, game:'Nigeria' },
  { id: 8, game:'Bangladesh' },
  { id: 9, game:'Russia' },
  { id: 10, game:'Mexico' },
  { id: 11, game:'Japan' },
  { id: 12, game:'Ethiopia' },
  { id: 13, game:'Philippines' },
  { id: 14, game:'Egypt' },
  { id: 15, game:'Vietnam' },
];

After adding the country’s data set, now we will include two useState hooks to handle the input value and suggestions, to display all the suggested phrases or results. Also, we will have handleChange function to capture the input data.

import React, {useState} from "react";
import { countries } from './fakedata';
import "./styles.css";

export default function App() {
  const [input, setInput] = useState("");
  const [suggestion, setSuggestions] = useState([]);

  const handleChange = (e) => {
    let value = e.target.value;
    setInput(value)
  } 

  return (
   <div className="App">
    <div className='title'>React Autocomplete/Autosuggest 🚀</div>
    <div className='form-wrapper'>
     <input className='input' 
      type='text' 
      placeholder="search country..."
      value={input}
      onChange={handleChange}
     />
    </div>
  </div>
  );
}

Now let’s work on the handleChange function, handleChange the function will be fired every time when the user changes the input value. On each change, the filter method will check the input values that match the country name and return the list. I am using the regex method which checks if the input string presents in any country name or not, independent of case sensitivity.

Note – The gi modifier is used to do a case insensitive search of all occurrences of a regular expression in a string.

All the country name which passes the test, filter method returns the array list of that country, which is set to setSuggestions.

const handleChange = (e) => {
    let value = e.target.value;
    let matches = [];

    if (value.length >= 1) {
      const regex = new RegExp(`${value}`, "gi");
      matches = countries.filter((item) => regex.test(item.game));
    }
    setSuggestions(matches);
    setInput(value)
  }  

Displaying AutoSuggestion Lists

So once we get the suggestion list, it is time now to map the suggestion so that the user can see the list of suggestions, I have used a condition that the suggestion list will appear only if any word matches the input value or not.

<div className="App">
  <div className='title'>React Autocomplete/Autosuggest 🚀</div>
  <div className='form-wrapper'>
    <input className='input' 
    type='text' 
    placeholder="search country..."
    value={input}
    onChange={handleChange}
    />
    {
      suggestion?.length > 0? (
        <div className='suggestion-wrapper'>
         {
           suggestion.map(item => {
             return (
              <div className='suggestions' key={item.id}>
                {item.game}
              </div>
              )
            })
          }
       </div>
     ) : null
    }
  </div>
</div>

Now we will add some CSS to make UI look good,

.suggestion-wrapper {
  position: absolute;
  top: 45px;
  left: 0;
  background-color: #fff;
  border-top: 1px solid #e5e5e5;
  padding: 10px 15px;
  width: 337px;
  text-align: start;
}

.suggestions {
  width: 100%;
  padding: 8px 5px;
  border-bottom: 1px solid #e5e5e5;
}

.suggestions:hover{
  background-color: #292929;
  color:#fff;
  cursor:pointer;
}

And Our UI will look something like this,

react autocomplete

Also read, A simple React Hook Form Validation with Formik and Yup

To add the extra layer of functionality we can add what happens when the user selects the value from suggestions or clear the search result. We will add another useState hook to capture the selected value, and to display that selected value we will display it at the bottom of the page, we add selectValue function to pass the selected value and clear the suggestions and input value data.

// state to store the selected value
const [select, setSelect] = useState("");


// to capture the value on click
const selectValue = (item) => {
 setSelect(item)
 setSuggestions("")
 setInput("")
}

// to capture the value on click and display it
{suggestion?.length > 0 ? (
   <div className="suggestion-wrapper">
     {suggestion.map((item) => {
       return (
           <div className="suggestions" 
            key={item.id}
            onClick={() => selectValue(item.game)}
           >
            {item.game}
          </div>
         );
       })}
    </div>
   ) : null}
 </div>
 <div className="select">
  Country Selected :<span className="selected">{select}</span>
 </div>

And now in order to clear the search, I will add an icon, on which when the user clicks, clearSearch the function will clear the input and suggestions list.

// function to clear the value
const clearSearch = () => {
  setInput("")
  setSuggestions("")
  setSelect("")
}

// icon where user can click to fire clearSearch function
<div className="icon" onClick={clearSearch}>
   {suggestion.length > 0 ? (
    <i class="fa fa-times"></i>
    ) : (
    <i class="fa fa-search"></i>
   )}
 </div>

Also read, How to add/remove input fields dynamically with Reactjs

Last Words

I hope you like this article, and I was able to demonstrate the tutorial in a clear and easy way. If you like my article please share it more with your friends and family, do check out more blogs on JavaScripts, React, and DSA. Please bookmark this page to get more awesome articles like these, I hope you have a nice day 😊!!