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
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
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;
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("");
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);
};
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);
};
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>
);
};
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;
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;
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;
}
Our application will look like the image below:
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.
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)