Published on

React와 JavaScript로 자동 검색 기능 구현하기

Authors
  • avatar
    Name
    Hyo814
    Twitter

React와 JavaScript로 자동 검색 기능 구현하기

https://mui.com/material-ui/react-autocomplete/

React와 JavaScript로 자동 검색 기능 구현하기

자동 검색 기능은 사용자가 텍스트를 입력하는 동안 실시간으로 검색 결과를 표시하는 기능입니다. 현대 웹 애플리케이션에서 자주 사용되는 UI 기능 중 하나이며, 검색과 관련된 사용자 경험을 크게 향상시킬 수 있습니다. 이번 글에서는 React를 사용하여 기본적인 자동 검색 기능을 구현하고, API와 연동하는 방법까지 단계별로 설명하겠습니다.


1. 기본 자동 검색 기능 구현

먼저, 간단한 배열 데이터를 필터링하여 자동 검색 기능을 구현해보겠습니다. 사용자가 검색어를 입력하면 해당 검색어와 일치하는 항목을 실시간으로 필터링하여 결과를 보여주는 방식입니다.

import React, { useState } from 'react'

const items = ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry', 'Fig', 'Grape', 'Honeydew']

const AutoSearch = () => {
  const [query, setQuery] = useState('')
  const [results, setResults] = useState([])

  const handleChange = (event) => {
    const value = event.target.value
    setQuery(value)
    if (value.length > 0) {
      const filteredResults = items.filter((item) =>
        item.toLowerCase().includes(value.toLowerCase())
      )
      setResults(filteredResults)
    } else {
      setResults([])
    }
  }

  return (
    <div>
      <input type="text" placeholder="Search..." value={query} onChange={handleChange} />
      {results.length > 0 && (
        <ul>
          {results.map((item, index) => (
            <li key={index}>{item}</li>
          ))}
        </ul>
      )}
    </div>
  )
}

export default AutoSearch

설명:

  • items 배열: 검색 대상이 되는 항목들을 미리 정의한 배열입니다.
  • useState: query는 사용자가 입력한 검색어를, results는 필터링된 검색 결과를 저장합니다.
  • handleChange 함수: 사용자가 입력한 검색어를 실시간으로 받아 items 배열에서 검색어와 일치하는 항목을 필터링합니다.
  • input 요소: 사용자가 검색어를 입력할 수 있는 입력 필드입니다.
  • 결과 표시: results 배열에 필터링된 항목이 있다면, 이를 화면에 리스트로 표시합니다.

이 기본적인 구현을 통해 로컬 데이터를 필터링하는 자동 검색 기능을 만들 수 있습니다.


2. API와 연동하기

실제 프로젝트에서는 검색어를 서버에 요청하여, 서버에서 반환된 검색 결과를 표시하는 방식으로 구현하는 경우가 많습니다. 이 예시에서는 Axios 라이브러리를 사용하여 API와 연동하는 방법을 보여드리겠습니다.

import React, { useState } from 'react'
import axios from 'axios'

const AutoSearchWithAPI = () => {
  const [query, setQuery] = useState('')
  const [results, setResults] = useState([])

  const handleChange = async (event) => {
    const value = event.target.value
    setQuery(value)
    if (value.length > 0) {
      try {
        const response = await axios.get(`/api/search?q=${value}`)
        setResults(response.data)
      } catch (error) {
        console.error('API 요청 중 오류 발생:', error)
      }
    } else {
      setResults([])
    }
  }

  return (
    <div>
      <input type="text" placeholder="Search..." value={query} onChange={handleChange} />
      {results.length > 0 && (
        <ul>
          {results.map((item, index) => (
            <li key={index}>{item}</li>
          ))}
        </ul>
      )}
    </div>
  )
}

export default AutoSearchWithAPI

설명:

  • Axios: API 요청을 위해 Axios 라이브러리를 사용합니다. axios.get() 메서드를 사용해 서버에 검색어를 포함한 GET 요청을 보냅니다.
  • 비동기 처리: API 요청은 비동기 함수handleChange 내에서 처리됩니다. 요청이 완료되면 반환된 데이터를 results에 저장하고, 이를 화면에 표시합니다.
  • 오류 처리: API 요청 중 오류가 발생하면 console.error()로 오류를 출력하여 디버깅할 수 있습니다.

3. 자동 검색 기능의 확장

위의 예시를 기반으로, 자동 검색 기능을 더 확장할 수 있습니다. 예를 들어:

  • 검색어에 따라 API 요청을 지연시키는 방식(디바운싱)을 추가하여, 불필요한 API 호출을 줄일 수 있습니다.
  • 검색어가 비어있을 때 이전 검색 결과를 유지하거나, 검색어가 짧을 때는 요청을 보내지 않는 로직을 추가하여 사용자 경험을 향상시킬 수 있습니다.

자동 검색 기능에서 API 요청의 결과를 화면에 표시하기 위해 어떤 라이브러리를 사용하나요?

자동 검색 기능에서 API 요청의 결과를 화면에 표시하기 위해 Axios라는 HTTP 클라이언트 라이브러리를 사용합니다. Axios는 비동기 API 호출을 간편하게 할 수 있게 해주는 라이브러리로, axios.get() 메서드를 통해 서버에 검색어를 포함한 GET 요청을 보내고, 그 결과를 받아서 처리합니다.

const response = await axios.get(`/api/search?q=${query}`)
setResults(response.data)

입력된 검색어가 짧을 경우, API 요청을 하지 않도록 처리하려면 어떤 로직을 추가해야 하나요?

검색어가 너무 짧을 경우에는 불필요한 API 요청을 피하는 것이 좋습니다. 이를 위해 검색어 길이에 대한 조건을 추가할 수 있습니다. 예를 들어, 검색어가 3자 이하일 때는 API 요청을 보내지 않도록 설정할 수 있습니다.

const handleChange = async (event) => {
  const value = event.target.value
  setQuery(value)

  // 검색어가 3자 이상일 때만 요청 수행
  if (value.length > 3) {
    const response = await axios.get(`/api/search?q=${value}`)
    setResults(response.data)
  } else {
    setResults([]) // 검색어가 짧으면 결과 초기화
  }
}

이 로직은 검색어 길이를 검사한 후, 조건에 맞는 경우에만 API 호출을 진행하므로 성능 최적화와 사용자 경험 향상에 도움이 됩니다.

실시간 검색 기능에서 검색 요청이 너무 빈번하게 발생하지 않도록 디바운싱(Debouncing)을 어떻게 구현할 수 있을까요?

디바운싱(Debouncing)은 사용자가 입력을 멈추고 일정 시간 지연된 후에 요청을 보내는 방식으로, 불필요하게 빈번한 API 요청을 줄여 성능을 최적화하는 방법입니다. 이를 구현하기 위해서는 **setTimeout()**을 사용하여 일정 시간 대기한 후 검색 요청을 보내고, 입력이 변경될 때마다 타이머를 초기화하면 됩니다.

다음은 디바운싱을 적용한 예시입니다:

import React, { useState, useEffect } from 'react'
import axios from 'axios'

const AutoSearchWithDebounce = () => {
  const [query, setQuery] = useState('')
  const [results, setResults] = useState([])
  const [debounceTimeout, setDebounceTimeout] = useState(null)

  const handleChange = (event) => {
    const value = event.target.value
    setQuery(value)

    // 이전 타이머를 제거하여 디바운싱
    if (debounceTimeout) clearTimeout(debounceTimeout)

    // 300ms 후에 API 요청 실행
    const newTimeout = setTimeout(async () => {
      if (value.length > 3) {
        const response = await axios.get(`/api/search?q=${value}`)
        setResults(response.data)
      } else {
        setResults([]) // 검색어가 짧으면 결과 초기화
      }
    }, 300)

    setDebounceTimeout(newTimeout)
  }

  return (
    <div>
      <input type="text" placeholder="Search..." value={query} onChange={handleChange} />
      {results.length > 0 && (
        <ul>
          {results.map((item, index) => (
            <li key={index}>{item}</li>
          ))}
        </ul>
      )}
    </div>
  )
}

export default AutoSearchWithDebounce

디바운싱 구현 설명:

  • *setTimeout()*을 사용하여 300ms의 지연을 주고, 그 후에 검색 요청을 보냅니다.
  • 사용자가 입력을 계속할 경우 이전에 설정된 타이머를 clearTimeout()으로 취소하여 요청이 계속해서 발생하지 않도록 합니다.
  • 입력이 멈춘 후 일정 시간이 지난 후에만 API 요청이 발생합니다.