debounce 트러블 슈팅

2022-06-05

Debounce

  • 빠르게 호출되는 중간 과정을 보여주지 않고 결과를 모아 보여줘도 문제가 되지 않을 경우 많이 사용
    (resize, keydown)

Lodash Documentation

요구사항

  • 키를 입력할때마다 검색 api를 호출하는 기능에 debounce를 적용하기

처음 작성했던 코드

lodash debounce를 사용해 처음 작성한 코드.

const handleSearch = debounce(() => {
  if (!onSearch) {
    return
  }
 
  ...
}, 500)

문제사항

그런데 debounce가 제대로 작동되지 않았다.
0.5초 후에 하나만 호출되는 것이 아니라 0.5초 이후에 한꺼번에 호출되었다.
입력할때마다 리액트 컴포넌트가 리렌더링되기 때문에 debounce도 계속 새 debounce를 호출한다.

해결

useCallback으로 처음에만 debounce를 불러와 재사용하도록 했다.

const handleSearch = useCallback(
  debounce(() => {
    if (!onSearch) {
      return
    }
 
    ...
  }, 500),
  [inputValue]
)

또다른 문제사항

  • search input에 abc를 입력할 경우 검색 api 3개가 호출되었다.
    (a, ab, abc)

  • 기대상황: abc를 연속적으로 입력할 경우 abc의 경우만 호출되어야한다.

해결

의존성 배열 삭제함으로써 a든 ab든 abc든 같은 debounce를 바라보게 해주었다.

const handleSearch = useCallback(
  debounce(() => {
    if (!onSearch) {
      return
    }
 
    ...
  }, DEFAULT_DEBOUNCE_TIME),
  []
)