Build a React autocomplete component from scratch
Tags: react, webdev
Published: 2021-08-02 17:44:31

**Written by [Fortune Ikechi] (https://blog.logrocket.com/author/fortuneikechi/)** ✏️

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](https://codesandbox.io/s/long-wave-0tgqs?file=/src/styles.css:0-602). 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:

```bash
npx create-react-app autocomplete-app
```

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:

```bash
cd autocomplete-app && yarn start 
```

## 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:

```javascript
import { useState } from "react";

const AutoComplete = ({ suggestions }) => {
   return (
    <>
      <input
        type="text"
      />
    </>
  );
};
export default AutoComplete;
```

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:

```javascript
 const [filteredSuggestions, setFilteredSuggestions] = useState([]);
  const [activeSuggestionIndex, setActiveSuggestionIndex] = useState(0);
  const [showSuggestions, setShowSuggestions] = useState(false);
  const [input, setInput] = useState("");
```

Now, let’s create the `onChange` method:

```javascript
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);
  };
```

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](https://blog.logrocket.com/returning-null-from-setstate-in-react-16-5fdb1c35d457/) 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:

```javascript
 const onClick = (e) => {
    setFilteredSuggestions([]);
    setInput(e.target.innerText);
    setActiveSuggestionIndex(0);
    setShowSuggestions(false);
  };
```

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`:

```javascript
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>
    );
  };
```

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:

```javascript
return (
    <>
      <input
        type="text"
        onChange={onChange}
        onKeyDown={onKeyDown}
        value={input}
      />
      {showSuggestions && input && <SuggestionsListComponent />}
    </>
  );
};
export default AutoComplete;
```

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:

```javascript
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;
```

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

```css
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;
}
```

Our application will look like the image below:

![React Autocomplete Demo](https://blog.logrocket.com/wp-content/uploads/2021/07/react-autocomplete-demo.png)

## 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] (https://www2.logrocket.com/react-performance-monitoring).

[![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6v4gw3tgq2topvafgpgz.png)](https://www2.logrocket.com/react-performance-monitoring)[![LogRocket Dashboard Free Trial Banner] (https://blog.logrocket.com/wp-content/uploads/2017/03/1d0cd-1s_rmyo6nbrasp-xtvbaxfg.png)](https://www2.logrocket.com/react-performance-monitoring)

[LogRocket] (https://www2.logrocket.com/react-performance-monitoring) 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] (https://www2.logrocket.com/react-performance-monitoring).