본문 바로가기
💻CODING/react. vue

[react] 검색어 자동완성 구현하기

by 코딩하는 갓디노 2022. 10. 6.

[react] 검색어 자동완성 구현하기

 

검색어 자동완성 구현하기

 

구현화면

 

구현내용

  • react hooks를 이용한 검색어 자동완성 기능
  • useSelect, useDispatch 사용
  • searchForFood 함수는 음식 찾기 api
  • onResetSearchedFood 찾은 음식 없애기 api
  • searchedFoodLists 필터링된 음식 리스트 - 최종 결과 데이터

 

검색어 자동완성 코드

그동안 검색어 자동완성 구현 방법을 여러가지 사용해왔었는데
주로 value값의 길이가 2이상부터 api 콜을 불러오는 식으로 하였으나,
이번에는 value값이 있을때마다 0.2초간 api 를 불러 데이터를 찾아주고, value 값이 없을때 데이터 리스트를 없애주는 방법으로 구현하였습니다. 

useEffect(() => { //검색어 자동 완성
    let params = { searchText: value }
    const debounce = setTimeout(() => {
        if (value) dispatch(searchForFood(params))//음식찾기 api
        else dispatch(onResetSearchedFood()) //찾은 음식 없애주기 api
    }, 200)
    return () => {
        clearTimeout(debounce)
    }
}, [value])

 

구현코드

import React, { useState, useEffect, useRef } from 'react';
import { useDispatch, useSelector } from "react-redux";
import { searchForFood, onResetSearchedFood } from "../../../../features/mobile/meal/addEatSlice";

const Test = () => {
    const dispatch = useDispatch()
    const inputRef = useRef(null)
    const { searchedFoodLists } = useSelector((state) => state.addEat)
    const [value, setValue] = useState('')
    const disabled = useRef(false)
    const onChangeInput = (e) => setValue(e.target.value)

    const onSearchForFood = () => { //검색버튼 클릭 이벤트
        if (disabled.current) return //disabled.current를 이용해 3초에 한번씩만 콜하기
        else {
            disabled.current = true
            if (!value) {
                //검색어를 입력하세요 알람 띄위기
            } else {
                let params = { searchText: value }
                dispatch(searchForFood(params)) //음식찾기 api 콜
                setValue('')
            }
            setTimeout(() => disabled.current = false, 3000)
        }
    }

    useEffect(() => { //검색어 자동 완성
        let params = { searchText: value }
        const debounce = setTimeout(() => {
            if (value) dispatch(searchForFood(params))//음식찾기 api
            else dispatch(onResetSearchedFood()) //찾은 음식 없애주기 api
        }, 200)
        return () => {
            clearTimeout(debounce)
        }
    }, [value])

    return (
        <>
            <div>
                <input
                    type='text'
                    placeholder={'음식명을 검색하세요.'}
                    onChange={(e) => onChangeInput(e)}
                    value={value}
                    id='foodSearch'
                    name='foodSearch'
                />
                <label onClick={onSearchForFood} htmlFor='foodSearch'>검색</label>
            </div>

         	<div className='mt-4 mb-14'>
                <h2 className='text-caption_1 text-gray_40 mb-4'>검색결과</h2>
                <ul className='flex flex-col gap-4'>
                    {searchedFoodLists.map(searchedFood => <FoodNameCard key={searchedFood.id} searchedFood={searchedFood} onAddFoodHandler={onAddFoodHandler} />)}
                </ul>
        	</div> 
          </>
    );
};

export default Test;
반응형

댓글