[React] 검색 입력에 Debounce 적용하기

MinJae·6일 전
1

React

목록 보기
21/21

💡 Debounce: 이벤트를 그룹화하여 특정 시간이 지난 후 하나의 이벤트만 발생하도록 하는 기술입니다. 검색 기능에 Debounce 기능을 추가하여, 사용자가 입력을 멈춘 후에만 API를 호출하도록 만들어 성능을 향상시킬 수 있습니다. 여기서는 useDebounce 훅을 만들어 검색 기능에 적용해 보겠습니다.

useDebounce 훅 만들기

// useDebounce.ts
import { useEffect, useState } from 'react';

const useDebounce = <T>(value: T, delay?: number): T => {
  const [debouncedValue, setDebouncedValue] = useState<T>(value);

  useEffect(() => {
    const timer = setTimeout(() => setDebouncedValue(value), delay || 2000);

    return () => {
      clearTimeout(timer);
    };
  }, [value, delay]);

  return debouncedValue;
};

export default useDebounce;

Debounce로 검색 기능 최적화하기

검색어 입력 시 바로 API 호출을 하지 않고, 입력이 멈춘 후 1초 후에만 API가 호출되도록 구성했습니다.

// SearchComponent.tsx
import { useState, useEffect } from 'react';
import useDebounce from './useDebounce';
import { getSearchMovies } from './api'; 
// getSearchMovies는 검색어를 받아 영화를 반환하는 함수입니다.

const SearchComponent = () => {
  const [searchTerm, setSearchTerm] = useState<string>('');
  const [movies, setMovies] = useState<Movie[]>([]);
  const debouncedSearchTerm = useDebounce(searchTerm, 1000);

  useEffect(() => {
    const fetchMovies = async () => {
      if (debouncedSearchTerm) {
        const result = await getSearchMovies(debouncedSearchTerm);
        setMovies(result.results || []);
      } else {
        setMovies([]);
      }
    };
    fetchMovies();
  }, [debouncedSearchTerm]);

  return (
    <>
      <input
        type="text"
        value={searchTerm}
        onChange={(e) => setSearchTerm(e.target.value)}
        placeholder="검색"
      />
      <ul>
        {movies.map((movie) => (
          <li key={movie.id}>{movie.title}</li>
        ))}
      </ul>
    </>
  );
};

export default SearchComponent;
  1. 디바운스 원리
    useDebouncesearchTerm이 변경될 때마다 딜레이 타이머를 새로 설정하고, 설정된 시간이 지나면 debouncedSearchTerm에 값을 전달합니다. 이로 인해 사용자가 입력을 멈춘 후에만 API 요청이 실행됩니다.

  2. 성능 개선 효과
    실시간 검색 시 매 입력마다 API 요청이 발생하지 않고, 입력이 완료된 후에만 요청이 진행되므로 불필요한 네트워크 요청을 줄일 수 있습니다.


✅ 참고

profile
반갑습니다
post-custom-banner

0개의 댓글