Search

Autocomplete Example with React16

post-title

We are going to learn how to build React Autocomplete. In this tutorial, we will step by step look at every aspect through which we can create an autosuggest component in React to make the user experience better.

We all are aware of Autocomplete; every day, we make lots of searches in Google and some other apps to get the result of our choice. Autocomplete is a feature which helps in predicting the rest of the word typed by a user. You must remember when you start typing something in the Google search bar; it shows you a list of suggestions based out of the keyword you type.

Autocomplete is helpful from the user as well as the user experience perspective. It makes users happy by saving their time and also by offering them several choices.

Implementing Autocomplete in React is significantly manageable, and it can be created into lots of ways. We will be using react-autocomplete npm module to achieve auto-suggest functionality.

React 16+ Autocomplete Tutorial

Let’s start building React autocomplete, first install the basic React project with React Autocomplete NPM module. Then, we will create a movie list array, and this array will serve the movies title to the user when a user starts typing into the input field or clicks on the input field. We will filter out the result and display the result to the user which is closely related to the user’s input value.

Set up React App

Enter the following command to install React app.

npx create-react-app react-autocomplete-tutorial

Enter into the project folder.

cd react-autocomplete-tutorial

Install React Autocomplete Library

Next, we will install React autocomplete library in React app.

npm i react-autocomplete --save

Set Up Movies Static Data in JSON Format

To build autocomplete in React, we need some static data. We will create a new file and custom function inside the src directory and name it movies-data.js. Insert the following movies list data and custom function in movies-data.js file.

export function MoviesData() {
    return [
        { "title": "The Shawshank Redemption", "rank": "1", "id": "tt0111161" },
        { "title": "The Godfather", "rank": "2", "id": "tt0068646" },
        { "title": "The Godfather: Part II", "rank": "3", "id": "tt0071562" },
        { "title": "Pulp Fiction", "rank": "4", "id": "tt0110912" },
        { "title": "The Good, the Bad and the Ugly", "rank": "5", "id": "tt0060196" },
        { "title": "The Dark Knight", "rank": "6", "id": "tt0468569" },
        { "title": "12 Angry Men", "rank": "7", "id": "tt0050083" },
        { "title": "Schindler's List", "rank": "8", "id": "tt0108052" },
        { "title": "The Lord of the Rings: The Return of the King", "rank": "9", "id": "tt0167260" },
        { "title": "Fight Club", "rank": "10", "id": "tt0137523" },
        { "title": "Star Wars: Episode V - The Empire Strikes Back", "rank": "11", "id": "tt0080684" },
        { "title": "The Lord of the Rings: The Fellowship of the Ring", "rank": "12", "id": "tt0120737" },
        { "title": "One Flew Over the Cuckoo's Nest", "rank": "13", "id": "tt0073486" },
        { "title": "Inception", "rank": "14", "id": "tt1375666" },
        { "title": "Goodfellas", "rank": "15", "id": "tt0099685" },
        { "title": "Star Wars", "rank": "16", "id": "tt0076759" },
        { "title": "Seven Samurai", "rank": "17", "id": "tt0047478" },
        { "title": "Forrest Gump", "rank": "18", "id": "tt0109830" },
        { "title": "The Matrix", "rank": "19", "id": "tt0133093" },
        { "title": "The Lord of the Rings: The Two Towers", "rank": "20", "id": "tt0167261" },
        { "title": "City of God", "rank": "21", "id": "tt0317248" },
        { "title": "Se7en", "rank": "22", "id": "tt0114369" },
        { "title": "The Silence of the Lambs", "rank": "23", "id": "tt0102926" },
        { "title": "Once Upon a Time in the West", "rank": "24", "id": "tt0064116" },
        { "title": "Casablanca", "rank": "25", "id": "tt0034583" },
        { "title": "The Usual Suspects", "rank": "26", "id": "tt0114814" },
        { "title": "Raiders of the Lost Ark", "rank": "27", "id": "tt0082971" },
        { "title": "Rear Window", "rank": "28", "id": "tt0047396" },
        { "title": "It's a Wonderful Life", "rank": "29", "id": "tt0038650" },
        { "title": "Psycho", "rank": "30", "id": "tt0054215" },
        { "title": "Léon: The Professional", "rank": "31", "id": "tt0110413" },
        { "title": "Sunset Blvd.", "rank": "32", "id": "tt0043014" },
        { "title": "American History X", "rank": "33", "id": "tt0120586" },
        { "title": "Apocalypse Now", "rank": "34", "id": "tt0078788" },
        { "title": "Terminator 2: Judgment Day", "rank": "35", "id": "tt0103064" },
        { "title": "Saving Private Ryan", "rank": "36", "id": "tt0120815" },
        { "title": "Memento", "rank": "37", "id": "tt0209144" },
        { "title": "City Lights", "rank": "38", "id": "tt0021749" },
        { "title": "Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb", "rank": "39", "id": "tt0057012" },
        { "title": "Alien", "rank": "40", "id": "tt0078748" },
        { "title": "Modern Times", "rank": "41", "id": "tt0027977" },
        { "title": "Spirited Away", "rank": "42", "id": "tt0245429" },
        { "title": "North by Northwest", "rank": "43", "id": "tt0053125" },
        { "title": "Back to the Future", "rank": "44", "id": "tt0088763" },
        { "title": "Life Is Beautiful", "rank": "45", "id": "tt0118799" },
        { "title": "The Shining", "rank": "46", "id": "tt0081505" },
        { "title": "The Pianist", "rank": "47", "id": "tt0253474" },
        { "title": "Citizen Kane", "rank": "48", "id": "tt0033467" },
        { "title": "The Departed", "rank": "49", "id": "tt0407887" },
        { "title": "M", "rank": "50", "id": "tt0022100" },
        { "title": "Paths of Glory", "rank": "51", "id": "tt0050825" },
        { "title": "Vertigo", "rank": "52", "id": "tt0052357" },
        { "title": "Django Unchained", "rank": "53", "id": "tt1853728" },
        { "title": "Double Indemnity", "rank": "54", "id": "tt0036775" },
        { "title": "The Dark Knight Rises", "rank": "55", "id": "tt1345836" },
        { "title": "Aliens", "rank": "56", "id": "tt0090605" },
        { "title": "Taxi Driver", "rank": "57", "id": "tt0075314" },
        { "title": "American Beauty", "rank": "58", "id": "tt0169547" },
        { "title": "The Green Mile", "rank": "59", "id": "tt0120689" },
        { "title": "Gladiator", "rank": "60", "id": "tt0172495" },
        { "title": "The Intouchables", "rank": "61", "id": "tt1675434" },
        { "title": "WALL·E", "rank": "62", "id": "tt0910970" },
        { "title": "The Lives of Others", "rank": "63", "id": "tt0405094" },
        { "title": "Toy Story 3", "rank": "64", "id": "tt0435761" },
        { "title": "The Great Dictator", "rank": "65", "id": "tt0032553" },
        { "title": "The Prestige", "rank": "66", "id": "tt0482571" },
        { "title": "A Clockwork Orange", "rank": "67", "id": "tt0066921" },
        { "title": "Lawrence of Arabia", "rank": "68", "id": "tt0056172" },
        { "title": "Amélie", "rank": "69", "id": "tt0211915" },
        { "title": "To Kill a Mockingbird", "rank": "70", "id": "tt0056592" },
        { "title": "Reservoir Dogs", "rank": "71", "id": "tt0105236" },
        { "title": "Das Boot", "rank": "72", "id": "tt0082096" },
        { "title": "The Lion King", "rank": "73", "id": "tt0110357" }
    ]
}

export function renderMovieTitle(state, val) {
    return (
        state.title.toLowerCase().indexOf(val.toLowerCase()) !== -1
    );
}

We declared renderMovieTitle() custom function which filters out the movie title typed by the user inside the search field. When the user starts typing in the search field, this function will look for the movie name in the MoviesData() and return the movie’s title as a suggested result.

Insert Autocomplete Module in App.js

We will build the autocomplete in React by inserting the given below code in src/App.js file.

import React, { Component } from 'react';
import { MoviesData, renderMovieTitle } from './movies-data';
import Autocomplete from 'react-autocomplete';
import './App.css';

class App extends Component {

  state = { val: '' };

  render() {
    return (
      <div className="autocomplete-wrapper">
        <h3>React Autocomplete Demo</h3>
        <Autocomplete
          value={this.state.val}
          items={MoviesData()}
          getItemValue={item => item.title}
          shouldItemRender={renderMovieTitle}
          renderMenu={item => (
            <div className="dropdown">
              {item}
            </div>
          )}
          renderItem={(item, isHighlighted) =>
            <div className={`item ${isHighlighted ? 'selected-item' : ''}`}>
              {item.title}
            </div>
          }
          onChange={(event, val) => this.setState({ val })}
          onSelect={val => this.setState({ val })}
        />
      </div>
    );
  }
}

export default App;

Let’s understand the API or methods we used above.

API Method Detail
value It’s an initial value, we set empty value.
items It is a list of data or an array, we are rendering the data from the MoviesData() array.
getItemValue Used to read the display value from each entry in items.
shouldItemRender This is an optional function, It is invoked for each entry in items and its return value is used to determine whether or not it should be displayed in the dropdown menu. By default all items are always rendered.
renderMenu This is an optional function, Invoked to generate the render tree for the dropdown menu. Ensure the returned tree includes every entry in items or else the highlight order and keyboard navigation logic will break. styles will contain { top, left, minWidth } which are the coordinates of the top-left corner and the width of the dropdown menu.
renderItem This method is invoked for each entry in items that also passes shouldItemRender to generate the render tree for each item in the dropdown menu. styles is an optional set of styles that can be applied to improve the look/feel of the items in the dropdown menu.
onChange This method is called when a user changes the value in the input field.
onSelect This method is called when a user chooses an item from the suggested dropdown list.

Style Autocomplete Module

Next, style the autocomplete module by adding the given below CSS code in src/index.css file.

* {
  box-sizing: border-box;
}

body {
  margin: 50px 0 0;
  text-align: center;
  font-family: sans-serif;
  background-color: #f6f8fa;
}

.autocomplete-wrapper {
  width: 350px;
  position: relative;
  display: inline-block;
}

.autocomplete-wrapper > div {
  width: 100%;
}

.autocomplete-wrapper input {
  border: 1px solid #cecece;
  padding: 12px 15px;
  font-size: 14px;
  width: 100%;
}

.autocomplete-wrapper input:focus {
  border-color: #0F67FF;
  box-shadow: none;
  outline: none;
}

.autocomplete-wrapper .dropdown {
  width: 100%;
  padding: 0;
  text-align: left;
  max-height: 280px;
  overflow: hidden;
  overflow-y: auto;
  background-color: #ffffff;
  border: 1px solid #0F67FF;
  border-top: none;
}

.autocomplete-wrapper .item  {
  display: block;
  cursor: pointer;
  font-size: 14px;
  padding: 15px;
}

.autocomplete-wrapper .item.selected-item {
  background-color: #0069ff;
  color: #FAFBFC;
}

.autocomplete-wrapper .item:hover {
  background-color: #0069ff;
  color: #FAFBFC;
}

Start the React app.

npm start

i hope you like this article.