React

React 에서 Debounce 다뤄보기

2025년 11월 19일

1️⃣ 디바운스(debounce)란?

디바운스는 “마지막 이벤트만 실행되게 하는 기법”입니다.

예를 들어, 검색창 입력에서:

ㄴ → 남 → 남ㅈ → 남자 → 남자니 → 남자니트

이렇게 1글자 입력할 때마다 API 호출을 하면 비효율적이므로,

사용자가 입력을 멈추고 일정 시간(예: 500ms) 이 지나면 그때 API를 호출하게 합니다.

➡️ 불필요한 렌더링/요청을 줄이는 성능 최적화 기술


2️⃣ 왜 React에서 debounce가 필요할까?

한 글자 입력할 때마다 새로운 state가 실행되면

✔ 리렌더링 반복

✔ 서버 API 요청 과도

✔ 부하 증가

예시:

const [query, setQuery] = useState('');
 
useEffect(() => {
  fetch(`/search?q=${query}`);
}, [query]);

입력할 때마다 fetch가 실행됨 → ❌ 비효율적

➡ 따라서 useDebounce 훅으로 입력 안정화 필요


3️⃣ useDebounce 커스텀 훅 구현 예시

import { useEffect, useState } from "react";
 
export function useDebounce(value, delay = 500) {
  const [debouncedValue, setDebouncedValue] = useState(value);
 
  useEffect(() => {
    // delay 시간 이후 값 업데이트
    const timer = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);
 
    // value가 바뀌면 기존 타이머 취소
    return () => clearTimeout(timer);
 
  }, [value, delay]);
 
  return debouncedValue;
}

4️⃣ useDebounce 훅이 돌아가는 원리 (핵심)


🧠 원리 핵심 개념

“입력이 변경될 때마다 타이머를 새로 만들고, 이전 타이머는 취소한다.

일정 시간 동안 값이 변하지 않으면 그때 값을 확정한다.”

이게 debounce의 전부입니다.


🔍 useDebounce 내부 동작 흐름

예제: delay = 500ms

1. value가 입력될 때마다 useEffect가 다시 실행됨

  • 즉시 setDebouncedValue 하지 않음 → 딜레이 시작

2. setTimeout으로 500ms 뒤에 실행될 예약 작업 생성

const timer = setTimeout(() => {
  setDebouncedValue(value)
}, 500);

3. 500ms 안에 value가 또 바뀌면?

→ cleanup 함수 실행 → 기존 타이머 제거

return () => clearTimeout(timer);

즉, 입력이 계속되면 타이머가 계속 초기화

그래서 API도 호출되지 않음

4. 사용자가 입력을 멈춘 순간

500ms 이후 실행된 setTimeout이 드디어 동작

➡ 드디어 debouncedValue가 업데이트됨

➡ 이 값변화가 API 호출을 유발


5️⃣ useDebounce 실제 사용 예시

function SearchBox() {
  const [text, setText] = useState("");
 
  const debouncedText = useDebounce(text, 500);
 
  useEffect(() => {
    if (debouncedText) {
      fetch(`/api/search?q=${debouncedText}`);
    }
  }, [debouncedText]);
 
  return (
    <inputvalue={text}
      onChange={(e) => setText(e.target.value)}
      placeholder="검색어 입력"
    />
  );
}

🔥 동작 흐름

  • 사용자가 입력할 때는 API 호출 없음
  • 입력 멈춘 뒤 500ms 지나면 API 호출
  • 완벽한 성능 최적화

6️⃣ 정리: useDebounce는 이렇게 동작한다

✔ 입력값 변화 → useEffect 재실행

✔ 이전 타이머 제거

✔ 새 타이머 설정

✔ delay 동안 추가 입력 없으면 최종 값 업데이트

✔ 최종 값(debouncedValue)만 API 호출에 사용

즉, 사용자가 멈춰야 비로소 값이 반영된다!