DEV Community

Cover image for Build a React autocomplete component from scratch
Matt Angelosanto for LogRocket

Posted on • Updated on • Originally published at blog.logrocket.com

Build a React autocomplete component from scratch

Written by Fortune Ikechi ✏️

Autocomplete is a feature that suggests words or phrases that complete a user’s initial input. In this article, we’ll build an autocomplete component from scratch in React.

For a better understanding of this tutorial, you should be familiar with JavaScript and React, and you should have Node.js and npm installed on your machine.

You can see the full code for this tutorial and a live version on CodeSandbox. Let’s get started!

Getting started

Let’s start by creating a new React project using npx. We’ll use autocomplete-app as the project name for our example:

npx create-react-app autocomplete-app
Enter fullscreen mode Exit fullscreen mode

Now, let’s navigate into the project directory and start the development server. The command below opens up a browser tab, rendering the default boilerplate application:

cd autocomplete-app && yarn start 
Enter fullscreen mode Exit fullscreen mode

Building a React autocomplete component

Inside your src folder, create a new file called Autocomplete.js. We’ll create a functional component that takes in a prop called suggestions. The functional component will return a button tag with the following properties destructured:

import { useState } from "react";

const AutoComplete = ({ suggestions }) => {
   return (
    <>
      <input
        type="text"
      />
    </>
  );
};
export default AutoComplete;
Enter fullscreen mode Exit fullscreen mode

The code above creates an autocomplete component. Inside, we rendered an input component, which takes a text input type. Let’s create some methods to apply in our component.

Defining methods

Let's define an onChange method inside of our autocomplete component. First, we need to define states for filtering suggestions, showing active suggestions, and taking inputs from a user:

 const [filteredSuggestions, setFilteredSuggestions] = useState([]);
  const [activeSuggestionIndex, setActiveSuggestionIndex] = useState(0);
  const [showSuggestions, setShowSuggestions] = useState(false);
  const [input, setInput] = useState("");
Enter fullscreen mode Exit fullscreen mode

Now, let’s create the onChange method:

const onChange = (e) => {
    const userInput = e.target.value;

    // Filter our suggestions that don't contain the user's input
    const unLinked = suggestions.filter(
      (suggestion) =>
        suggestion.toLowerCase().indexOf(userInput.toLowerCase()) > -1
    );

    setInput(e.target.value);
    setFilteredSuggestions(unLinked);
    setActiveSuggestionIndex(0);
    setShowSuggestions(true);
  };
Enter fullscreen mode Exit fullscreen mode

Whenever a user changes the input value, the onChange method will fire, filtering through a list of suggestions and returning those that do not contain the user’s input.

We used React’s setState Hook to set a user’s property to contain a value. We also set suggestions with the setShowSuggestions state, which displays our list to the user. Every time the input changes, setActiveSuggestions displays a new list of suggestions to the user.

Adding a suggestion

Let’s add an onClick event in our Autocomplete.js file for adding a suggestion:

 const onClick = (e) => {
    setFilteredSuggestions([]);
    setInput(e.target.innerText);
    setActiveSuggestionIndex(0);
    setShowSuggestions(false);
  };
Enter fullscreen mode Exit fullscreen mode

In the code block above, we created an onClick event that will be emitted when a user clicks on a suggestion. We used React’s setState Hook to update the user’s input and reset our current state.

Selecting between autocomplete suggestions

An important feature to add to our application is an onKeyDown method. When a user is given two or more suggestions, the user can use the keyDown button to select any of the autocomplete suggestions.

The first condition checks if the user’s input matches keyCode 13, the enter key. If it does, it runs the setInput method to add the user’s input and close the suggestions list.

If the user presses the up arrow key, which has keyCode 38, the second condition will decrement the index. If the index is 0, the second condition will return nothing in the activeSuggestion prop.

If the user inputs keyCode 40, the condition will increase the index in the setActiveSuggestion prop. If the index matches the length of the filteredSuggestions, it will return nothing.

Create a SuggestionsListComponent

For our last method, let’s create a SuggestionsListComponent, which will flag active suggestions with classes so that we can use them in our application. We’ll also add an alert for when a user inputs a word that is not in our SuggestionsList:

const SuggestionsListComponent = () => {
    return filteredSuggestions.length ? (
      <ul class="suggestions">
        {filteredSuggestions.map((suggestion, index) => {
          let className;
          // Flag the active suggestion with a class
          if (index === activeSuggestionIndex) {
            className = "suggestion-active";
          }
          return (
            <li className={className} key={suggestion} onClick={onClick}>
              {suggestion}
            </li>
          );
        })}
      </ul>
    ) : (
      <div class="no-suggestions">
        <em>No suggestions, you're on your own!</em>
      </div>
    );
  };
Enter fullscreen mode Exit fullscreen mode

The SuggestionsListComponent method checks whether the props that the user entered have any value. If the values exist, the SuggestionsListComponent method assigns a value that loops through the filteredSuggestions property.

If the index matches the value in the activeSuggestion property, it adds an active class to an active suggestion. When the onClick method is used, the suggestionListComponent method will return an ordered list of the suggestions and assign a class name to a suggestion.

If the values in showSuggestions and userInput do not exist in our database, the user receives a text saying there are no suggestions.

Inputting user text

Let’s finish our autocomplete component by creating an input field for a user to input text if the conditions listed in the suggestionsListComponent aren’t met:

return (
    <>
      <input
        type="text"
        onChange={onChange}
        onKeyDown={onKeyDown}
        value={input}
      />
      {showSuggestions && input && <SuggestionsListComponent />}
    </>
  );
};
export default AutoComplete;
Enter fullscreen mode Exit fullscreen mode

Finally, let’s navigate to the App.js file inside our project directory and add the code snippet below. We’ll create an app component that takes in our autocomplete component and a list of suggestions in an array:

import React from "react";
import Autocomplete from "./Autocomplete";
import "./styles.css";

const App = () => {
  return (
    <div>
      <h1>React Autocomplete Demo</h1>
      <h2>Start typing and experience React autocomplete!</h2>
      <Autocomplete
        suggestions={[
          "Alligator",
          "Bask",
          "Crocodilian",
          "Death Roll",
          "Eggs",
          "Jaws",
          "Reptile",
          "Solitary",
          "Tail",
          "Wetlands"
        ]}
      />
    </div>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

Now, let’s style our application! Add the following styles below to your styles.css file:

body {
  font-family: sans-serif;
}
input {
  border: 1px solid #999;
  padding: 0.5rem;
  width: 300px;
}
.no-suggestions {
  color: #999;
  padding: 0.5rem;
}
.suggestions {
  border: 1px solid #999;
  border-top-width: 0;
  list-style: none;
  margin-top: 0;
  max-height: 143px;
  overflow-y: auto;
  padding-left: 0;
  width: calc(300px + 1rem);
}
.suggestions li {
  padding: 0.5rem;
}
.suggestion-active,
.suggestions li:hover {
  background-color: #008f68;
  color: #fae042;
  cursor: pointer;
  font-weight: 700;
}
.suggestions li:not(:last-of-type) {
  border-bottom: 1px solid #999;
}
Enter fullscreen mode Exit fullscreen mode

Our application will look like the image below:

React Autocomplete Demo

Conclusion

In this tutorial, we covered setting up a React project, building an autocomplete component, and styling our application.

Not only can an autocomplete feature save your users time, it may also guide users to more relevant searches. Now, you know how to build an autocomplete component from scratch in your React application!


Full visibility into production React apps

Debugging React applications can be difficult, especially when users experience issues that are hard to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.

Alt TextLogRocket Dashboard Free Trial Banner

LogRocket is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps — start monitoring for free.

Top comments (0)