Front-end/React

[React] 키워드 추천 자동완성 기능 구현

늘이 2024. 11. 8. 22:14

 

1. 구현 내용

사용자가 키워드를 입력하면 해당 키워드로 시작하는 제안 키워드가 나오고, tab 키를 누르면 제안 키워드가 입력되는 기능

 

2. 코드 

import React, { useState } from "react";

import menuList from "./MenuList.js";
import "./App.css";

function App() {
  const [menuName, setMenuName] = useState("");
  const [filteredMenus, setFilteredMenus] = useState([]); // 메뉴명 필터링 결과(=자동 완성 리스트)
  const [suggestion, setSuggestion] = useState(""); // 메뉴명 자동완성 제안 텍스트

  // 메뉴명 필드 입력 시 필터링 및 자동완성 제안 텍스트 설정
  const handleMenuNameChange = (e) => {
    const input = e.target.value;
    console.log("메뉴명 입력:", input);
    setMenuName(input); // 입력한 내용을 menuName으로 업데이트

    if (input) {
      const matchedMenu = menuList.find((menu) => menu.startsWith(input));
      setFilteredMenus(menuList.filter((menu) => menu.includes(input)));
      setSuggestion(matchedMenu ? matchedMenu.slice(input.length) : ""); // 제안 텍스트 설정
    } else {
      setFilteredMenus([]);
      setSuggestion("");
    }
  };

  // 메뉴명 입력 필드에서 Tab 키 누를 때 추천 단어로 자동 완성
  const handleMenuNameKeyDown = (e) => {
    if (e.key === "Tab" && suggestion) {
      e.preventDefault(); // 기본 탭 동작 막기
      setMenuName(menuName + suggestion); // 메뉴명에 추천 단어 추가
      setSuggestion(""); // 추천 단어 초기화
      setFilteredMenus([]); // 추천 목록 초기화
    }
  };

  return (
    <div className="menu-section">
      <label htmlFor="menuName">메뉴명</label>
      <div className="input-with-suggestion">
        <input
          type="text"
          id="menuName"
          value={menuName}
          onChange={(e) => {
            handleMenuNameChange(e);
            e.target.style.setProperty("--input-length", e.target.value.length);
          }}
          onKeyDown={handleMenuNameKeyDown} // Tab 키 이벤트 추가
        />
        {suggestion && (
          <span className="suggestion">
            {menuName}
            <span className="suggestion-text">{suggestion}</span>
          </span>
        )}
      </div>
    </div>
  );
}

export default App;

 

3. css

.menu-section {
  display: flex;
  flex-direction: column;
  position: relative;
  width: 30%;
  padding: 20px;
}

.menu-section label {
  color: #636369;
  font-weight: bold;
  font-size: 16px;
  margin-top: 17px;
  margin-bottom: 15px;
  padding-left: 10px;
}

.input-with-suggestion {
  position: relative;
  width: 100%;
  display: flex;
  align-items: center;
}

.input-with-suggestion input {
  padding: 15px;
  font-size: 15px;
  border: 1px solid #d3d5dc;
  border-radius: 15px;
  width: 100%;
  height: 5vh;
  box-sizing: border-box;
}

.suggestion {
  position: absolute;
  top: 50%;
  left: 16px;
  transform: translateY(-50%);
  color: transparent; /* 기본 텍스트는 투명하게 */
  font-size: 15px;
  pointer-events: none;
  white-space: nowrap;
}

.suggestion-text {
  color: rgba(28, 144, 251, 0.5); /* 색상과 투명도 */
}

 

4. 문제 발생

  • 영어 입력은 문제가 없었지만 한글의 경우 문제가 발생함
  • 아래와 같이 입력중이던 마지막 문자가 추천키워드 뒤에 나온다는 것

5. 해결방법

https://k-sky.tistory.com/920

 

[React] 자동완성 기능 구현 중 한글이 두번 써지는 현상 해결하기

1. 문제 상황영어 입력은 문제가 없었지만 한글 입력의 경우 문제 발생했습니다.아래와 같이 입력중이던 마지막 문자가 추천키워드 뒤에 나온다는 것입니다.  2. 원인 IME의 조합 상태: 한글 IME

k-sky.tistory.com