본문 바로가기
Dev-diary/에러 또 에러

검색 Debounce 직접 구현하기 (feat. 재할당 & 비동기)

by ciocio 2022. 4. 12.

👀 검색창 자동완성 기능 만들 때 서버에 너무 많은 요청을 보내게 되는 문제 발생 ❗

 

lodash의 debounce 함수를 이용할 수도 있지만 직접 구현할 수도 있다 ㅎㅎ 😊

그런데 구현하다가 아차 싶었던, 내가 실수했던 부분이 있어서 기록에 남긴다.

 


 

input 창에 입력될 때마다 데이터가 콘솔에 찍히는 중

 

const handleSearchBar = (event: React.ChangeEvent<HTMLInputElement>) => {
  // 내부
  let timer: any = 0;
  const searchValue = event.target.value;

  if (timer) {
    console.log('clear time');
    clearTimeout(timer);
  }
  timer = setTimeout(() => {
    axios({
      method: 'get',
      url: '서버 URL'
    })
    .then((res) => {
      console.log(res.data);
    })
    .catch((err) => {
      console.log(err);
    })
  }, 300);
}

 

 

Input 입력 글자와 상관없이 1번만 데이터 출력

 

// 외부
let timer: any = 0;

const handleSearchBar = (event: React.ChangeEvent<HTMLInputElement>) => {
  const searchValue = event.target.value;
    
  if (timer) {
    console.log('clear time');
    clearTimeout(timer);
  }
  timer = setTimeout(() => {
    axios({
      method: 'get',
      url: `http://localhost:4000/vegetables?q=${searchValue}`
    })
    .then((res) => {
      console.log(res.data);
    })
    .catch((err) => {
      console.log(err);
    })
  }, 300);
}

 

두 코드의 차이점은 timer 변수가 선언된 위치 ...

첫 번째 코드는 함수 내부에 선언됨으로써 리랜더링 될때마다 변수도 초기화됐다.

그래서 항상 0이라 .. 내가 원하는 동작이 실행되지 않음 😨

 

이 단순한 원리를 찾기까지 꽤 걸려서 ^__^

클로저 함수로 구현하면 전역에 변수를 남기지 않고 좋을 것 같다 🤔

 

내가 setTimeout 함수를 0.2초뒤에 실행되게끔 설정해놔서 차이가 잘 안보일 수도 있다 !

더 길게 설정하면 차이를 확연히 알 수 있음 :)

 

반응형

댓글