사용자 지정 React 자동 완성 검색 구성 요소 구축

이 튜토리얼에서는 사용자가 검색 쿼리를 입력할 때 제안을 제공하는 React 자동 완성 검색 구성 요소를 구축할 것입니다. React에는 자동 완성 기능을 제공하는 여러 라이브러리가 있지만 처음부터 사용자 지정 구성 요소를 만들 것입니다.

Create React App을 사용하여 기본 앱을 설정하여 시작하겠습니다.

npx create-react-app react-autocomplete-search


다음으로 data.js 폴더에 새 /src 파일을 만듭니다. 이 파일에는 자동 완성 제안을 제공하는 데 사용할 배열이 포함되어 있습니다. 실제로는 이 파일을 API 호출로 대체하여 데이터를 제공할 수 있습니다.

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


그런 다음 AutoComplete.js 폴더에 다음 구조로 새 /src 파일을 만듭니다.

import { useState } from "react";

const AutoComplete = ({ data }) => {
  return (
    <div className="autocomplete">
      <input type="text" />     
    </div>
  );
};

export default AutoComplete;


이제 State 변수로 시작하는 구성 요소 빌드를 시작할 수 있습니다.

const [suggestions, setSuggestions] = useState([]);
const [suggestionIndex, setSuggestionIndex] = useState(0);
const [suggestionsActive, setSuggestionsActive] = useState(false);
const [value, setValue] = useState("");


  • suggestions – 자동 완성 메뉴를 채우는 데 사용할 제안 배열.
  • suggestionIndex - 키보드 탐색에 사용되는 활성 제안의 색인입니다.
  • suggestionsActive – 자동 완성 제안의 가시성을 전환하는 데 사용됩니다.
  • value – 사용자가 선택한 자동 완성 제안.

  • 자동 완성 제안은 사용자가 쿼리를 입력하는 동안 트리거되어야 합니다. 이를 위해 입력 필드의 변경 사항을 모니터링하는 onChange 이벤트를 사용합니다. 그런 다음 autoCompleteData를 필터링하여 관련 제안을 찾습니다.

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


    또한 사용자는 자동 완성 제안을 클릭하고 해당 제안이 입력 필드를 채우도록 할 수 있어야 합니다. 이를 위해 onClick 이벤트에 의해 트리거되는 다음 함수를 추가해야 합니다.

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


    사용자가 각 제안 사이를 탐색하고 키보드를 사용하여 제안을 선택할 수 있도록 keyDown 이벤트를 사용하여 위쪽/아래쪽 화살표 및 Enter 키를 눌렀을 때 수신 대기합니다.

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


    실제 제안을 위해 Suggestions 구성 요소를 생성합니다.

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


    이렇게 하면 suggestions 배열이 정렬되지 않은 HTML 목록으로 출력됩니다. 키워드의 위쪽/아래쪽 화살표를 사용하여 사용자가 선택한 목록 항목의 스타일을 지정할 수 있는 조건부active 클래스를 추가했습니다. 구성 요소가 완료되면 다음 CSS를 추가하여 이를 확인할 수 있습니다.

    .active {
      background: lightgray;
    }
    


    구성 요소 업데이트를 완료하려면 다음과 같이 return 문을 업데이트합니다.

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


    완성된AutoComplete 구성 요소의 모양은 다음과 같습니다.

    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;
    


    마지막으로 구성 요소와 데이터를 로드하도록 업데이트App.js할 수 있습니다.

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


    이것이 이 튜토리얼의 전부입니다. 이제 React 애플리케이션에 쉽게 추가할 수 있는 작동하는 자동 완성 검색 구성 요소가 있어야 합니다. 이 튜토리얼에 대한 full source code 및 w3collective에 게시된 모든 튜토리얼을 GitHub에서 얻을 수 있습니다.

    좋은 웹페이지 즐겨찾기