Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
September 6, 2022 06:47 am GMT

Build a custom React autocomplete search component

In this tutorial well be building a React autocomplete search component that provides suggestions as a user types a search query. There are a number of libraries that provide autocomplete functionality in React but well be creating a custom component from scratch.

Lets get started by setting up a basic app using Create React App:

npx create-react-app react-autocomplete-search

Next create a new data.js file in the /src folder. This file contains an array that will be used to provide the autocomplete suggestions. In the real world you might want to replace this file with an API call to provide the data:

export const autoCompleteData = [    "Asparagus",    "Beetroot",    "Broccoli",    "Cabbage",     "Carrot",     "Cauliflower",     "Celery",     "Corn",     "Eggplant",     "Lettuce",     "Mushroom",     "Onion",     "Parsnip",     "Pea",     "Potato",     "Pumpkin",     "Radish",     "Spinach",        "Tomato",     "Turnip",   ];

Then create a new AutoComplete.js file in the /src folder with the following structure:

import { useState } from "react";const AutoComplete = ({ data }) => {  return (    <div className="autocomplete">      <input type="text" />         </div>  );};export default AutoComplete;

We can now start building the component starting with the State variables:

const [suggestions, setSuggestions] = useState([]);const [suggestionIndex, setSuggestionIndex] = useState(0);const [suggestionsActive, setSuggestionsActive] = useState(false);const [value, setValue] = useState("");
  • suggestions array of suggestions to used populate the autocomplete menu.
  • suggestionIndex index of the active suggestion used for keyboard navigation.
  • suggestionsActive used to toggle the visibility of the autocomplete suggestions.
  • value autocomplete suggestion that the user has selected.

The autocomplete suggestions need to be triggered while the user is typing a query. For this well use an onChange event that monitors for changes to the input field. We then filter the autoCompleteData to find the relevant suggestions:

const handleChange = (e) => {  const query = e.target.value.toLowerCase();  setValue(query);  if (query.length > 1) {    const filterSuggestions = data.filter(      (suggestion) => suggestion.toLowerCase().indexOf(query) > -1    );    setSuggestions(filterSuggestions);    setSuggestionsActive(true);  } else {    setSuggestionsActive(false);  }};

Users will also need to be able to click an autocomplete suggestion and have that suggestion populate the input field. For this well need to add the following function that is triggered by an onClick event:

const handleClick = (e) => {  setSuggestions([]);  setValue(e.target.innerText);  setSuggestionsActive(false);};

To allow users to navigate between each of the suggestions and also select a suggestion using the keyboard well use a keyDown event to listen for when either the up/down arrow and enter keys are pressed:

const handleKeyDown = (e) => {  // UP ARROW  if (e.keyCode === 38) {    if (suggestionIndex === 0) {      return;    }    setSuggestionIndex(suggestionIndex - 1);  }  // DOWN ARROW  else if (e.keyCode === 40) {    if (suggestionIndex - 1 === suggestions.length) {      return;    }    setSuggestionIndex(suggestionIndex + 1);  }  // ENTER  else if (e.keyCode === 13) {    setValue(suggestions[suggestionIndex]);    setSuggestionIndex(0);    setSuggestionsActive(false);  }};

For the actual suggestions well create a Suggestions component:

const Suggestions = () => {  return (    <ul className="suggestions">      {suggestions.map((suggestion, index) => {        return (          <li            className={index === suggestionIndex ? "active" : ""}            key={index}            onClick={handleClick}          >            {suggestion}          </li>        );      })}    </ul>  );};

This outputs the suggestions array into an unordered HTML list. Note weve added a conditional active class which will allow us to style the list item the user has selected using the up/down arrows on the keyword. You can add the following CSS to see this in action once the component is complete:

.active {  background: lightgray;}

To complete the component update the return statement as follows:

return (  <div className="autocomplete">    <input      type="text"      value={value}      onChange={handleChange}      onKeyDown={handleKeyDown}    />    {suggestionsActive && <Suggestions />}  </div>);

Heres how the completed AutoComplete component should look:

import { useState } from "react";const AutoComplete = ({ data }) => {  const [suggestions, setSuggestions] = useState([]);  const [suggestionIndex, setSuggestionIndex] = useState(0);  const [suggestionsActive, setSuggestionsActive] = useState(false);  const [value, setValue] = useState("");  const handleChange = (e) => {    const query = e.target.value.toLowerCase();    setValue(query);    if (query.length > 1) {      const filterSuggestions = data.filter(        (suggestion) =>          suggestion.toLowerCase().indexOf(query) > -1      );      setSuggestions(filterSuggestions);      setSuggestionsActive(true);    } else {      setSuggestionsActive(false);    }  };  const handleClick = (e) => {    setSuggestions([]);    setValue(e.target.innerText);    setSuggestionsActive(false);  };  const handleKeyDown = (e) => {    // UP ARROW    if (e.keyCode === 38) {      if (suggestionIndex === 0) {        return;      }      setSuggestionIndex(suggestionIndex - 1);    }    // DOWN ARROW    else if (e.keyCode === 40) {      if (suggestionIndex - 1 === suggestions.length) {        return;      }      setSuggestionIndex(suggestionIndex + 1);    }    // ENTER    else if (e.keyCode === 13) {      setValue(suggestions[suggestionIndex]);      setSuggestionIndex(0);      setSuggestionsActive(false);    }  };  const Suggestions = () => {    return (      <ul className="suggestions">        {suggestions.map((suggestion, index) => {          return (            <li              className={index === suggestionIndex ? "active" : ""}              key={index}              onClick={handleClick}            >              {suggestion}            </li>          );        })}      </ul>    );  };  return (    <div className="autocomplete">      <input        type="text"        value={value}        onChange={handleChange}        onKeyDown={handleKeyDown}      />      {suggestionsActive && <Suggestions />}    </div>  );};export default AutoComplete;

Finally we can update App.js to load the component and the data:

import Autocomplete from "./AutoComplete";import { autoCompleteData } from "./data.js";function App() {  return (    <div className="App">      <Autocomplete data={autoCompleteData} />    </div>  );}export default App;

Thats all for this tutorial, you should now have a working autocomplete search component that can easily be dropped into a React application. You can get the full source code for this tutorial and all tutorials published on w3collective from GitHub.


Original Link: https://dev.to/michaelburrows/build-a-custom-react-autocomplete-search-component-2hcd

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To