Skip to main content

Build Autocomplete Search in React

In our previous React tutorial, we have explained how to create React Select Dropdown List from API. In this tutorial, we will explain how to create React Autosuggest Search using API.

The autosuggest search is a very user friendly feature of web application in which partial text search ebabled to display dropdown list of matching option values to select from.

In this tutorial, we will implement autosuggest search component to allow users to enter partial search text, an api request made to fetch data based on search text and display in dropdown list as suggested items to select fom suggested list.

We will use react react-autosuggest package to implement autosuggest functionality.

So let’s start to implement React Autosuggest Search using API.

Prerequisites

  1. Yarn/npm installed.
  2. The basic knowledge of HTML, JavaScript (ES6), and CSS.

React Application Setup

First we will create a react application react-autocomplete-app using below command.

$ npx create-react-app react-autocomplete-app

we will move into our newly created application.

$ cd react-autocomplete-app

Now we will run our react application using below command.

$ npm start

Install React Autosuggest Package

As we are going to implement autosuggest functionality, so we need to install react-autosuggest package using below command.

$ npm install react-autosuggest --save

Create Autosuggest Component in Application

We will create a new class component AutoSuggest in autosuggest.jsfile. So will create a new directory src/components and create components file autosuggest.js into src/components directory.

The AutoSuggest component is created by adding <Autosuggest /> component to render suggestion list.

import React from 'react';
import Autosuggest from 'react-autosuggest';
import './autosuggest.css';

class AutoSuggest extends React.Component {
    constructor() {
        super();
        
        this.state = {
            value: '',
            suggestions: []
        };
    }

    // get response data from api
    getSuggestions = async (value) => {
        const searchValue = value.trim().toLowerCase();
        let response = await fetch("http://www.omdbapi.com/?s=" + searchValue + "&apikey=492e39fd");
        let data = await response.json()
        return data;
    };

    // Trigger suggestions
    getSuggestionValue = suggestion => suggestion.Title;

    // Render suggestion Option
    renderSuggestion = suggestion => (
        <span className="sugg-option">
            <span className="icon-wrap"><img src={suggestion.Poster} /></span>
            <span className="name">
                {suggestion.Title}
            </span>
        </span>
    );

    // OnChange event handler
    onChange = (event, { newValue }) => {
        this.setState({
            value: newValue
        });
    };

    // Suggestion rendering when user types
    onSuggestionsFetchRequested = ({ value }) => {
        this.getSuggestions(value)
            .then(data => {
                if (data.Error) {
                    this.setState({
                        suggestions: []
                    });
                } else {
                    this.setState({
                        suggestions: data.Search
                    });
                }
            })
    };
    
    onSuggestionsClearRequested = () => {
        this.setState({
            suggestions: []
        });
    };

    render() {
        const { value, suggestions } = this.state;

        const inputProps = {
            placeholder: 'Type movie name',
            value,
            onChange: this.onChange
        };

        // Adding AutoSuggest component
        return (
            <Autosuggest
                suggestions={suggestions}
                onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
                onSuggestionsClearRequested={this.onSuggestionsClearRequested}
                getSuggestionValue={this.getSuggestionValue}
                renderSuggestion={this.renderSuggestion}
                inputProps={inputProps}
            />
        );
    }
}

export default AutoSuggest;

In above component, we are fetching the autosuggest search result from http://www.omdbapi.com API. The API returns matching results as response to display in autosuggest list.

In method getSuggestions, we are using JavaScript fetch() function to make API request and returns promise to the onSuggestionsFetchRequested method to update the suggestions value.

getSuggestions = async (value) => {
	const searchValue = value.trim().toLowerCase();
	let response = await fetch("http://www.omdbapi.com/?s=" + searchValue + "&apikey=492e39fd");
	let data = await response.json()
	return data;
};

We have used async and await functions to handle the promise returned by the fetch() method.

The renderSuggestion method is returning the sugestion list custom template with title and image to display in suggestion list.

renderSuggestion = suggestion => (
	<span className="sugg-option">
		<span className="icon-wrap"><img src={suggestion.Poster} /></span>
		<span className="name">
			{suggestion.Title}
		</span>
	</span>
);

Adding CSS for Autosuggest Component

We will create css file autosuggest.css into src/components directory. We will import this css file into autosuggest.js component.

.react-autosuggest__container {
  position: relative;
}

.react-autosuggest__input {
  width: 240px;
  height: 30px;
  padding: 10px 20px;
  font-family: "Open Sans", sans-serif;
  font-weight: 300;
  font-size: 16px;
  border: 1px solid #aaa;
  border-radius: 4px;
  -webkit-appearance: none;
}

.react-autosuggest__input--focused {
  outline: none;
}

.react-autosuggest__input::-ms-clear {
  display: none;
}

.react-autosuggest__input--open {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}

.react-autosuggest__suggestions-container {
  display: none;
}

.react-autosuggest__suggestions-container--open {
  display: block;
  position: absolute;
  top: 51px;
  width: 280px;
  border: 1px solid #aaa;
  background-color: #fff;
  font-family: "Open Sans", sans-serif;
  font-weight: 300;
  font-size: 16px;
  border-bottom-left-radius: 4px;
  border-bottom-right-radius: 4px;
  z-index: 2;
}

.react-autosuggest__suggestions-list {
  margin: 0;
  padding: 0;
  list-style-type: none;
  overflow: auto;
  max-height: 400px;
}

.react-autosuggest__suggestion {
  cursor: pointer;
  padding: 10px 20px;
}

.react-autosuggest__suggestion--highlighted {
  background-color: #ddd;
}

.react-autosuggest__section-container {
  border-top: 1px dashed #ccc;
}

.react-autosuggest__section-container--first {
  border-top: 0;
}

.react-autosuggest__section-title {
  padding: 10px 0 0 10px;
  font-size: 12px;
  color: #777;
}

.react-autosuggest__suggestions-list {
  margin: 0;
  padding: 0;
  list-style-type: none;
  overflow: auto;
  max-height: 400px;
}

.sugg-option {
  display: flex;
}
.icon-wrap img {
  width: 50px;
  margin-right: 10px;
}
.sugg-option .name {
}

Using AutoSuggest Component in App.js

After creating AutoSuggest component, we will import it in src/App.js. We will also use AutoSuggest to render autosuggest list.

import React from 'react';
import './App.css';
import AutoSuggest from './components/autosuggest';

function App() {
  return (
    <div className="App">     
	  
	  <h1>Search Movie</h1>
      <AutoSuggest />

    </div>
  );
}

export default App;

We will update the src/App.css with following CSS to style app page.

.App {
  padding: 50px;
}

.App-logo {
  height: 40vmin;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .App-logo {
    animation: App-logo-spin infinite 20s linear;
  }
}

.App-header {
  background-color: #282c34;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: white;
}

.App-link {
  color: #61dafb;
}

@keyframes App-logo-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}