카테고리 없음

debounce로 검색 결과 api를 지연시켜보자

아보카도 있었어! 2023. 4. 12. 17:29

JavaScript에서 debounce(디바운스)는 유저가 입력할 때마다 코드를 오직 한 번씩만 실행되도록 해 주는 함수이다.

검색박스의 제안, 텍스트 필드의 자동 저장, 버튼의 더블 클릭 제거 등이 모두 debounce를 이용하는 사례이다.

 

  • debounce란?

debounce는 전자 공학에서 온 용어이다. 우리가 TV리모컨을 누를 때, 여러 번을 눌러도 마지막에 누른 버튼만 동작하는 것처럼, 일단 버튼으로부터 신호를 받았다면 다시 버튼을 누르는 것이 불가능한 버튼으로부터 온 신호는 처리하지 않는 예를 들 수 있다.(마지막 요청만 처리한다는 의미이다)

 

사용자가 타이핑을 끝내고 난 뒤에만 추천 검색어를 띄우고 싶다고 해보자.

또는 작성한 양식의 내용을 저장하고자 하지만, 매번 '저장'이 일어나 서버 측의 DB를 너무 자주 건드리는 일이 발생하지 않도록 내용이 안정적일 때(적극적으로 변경하지 않을 때)만 그제야 '저장' 행위가 이루어지도록 하고 싶다고 해 보자.

 

자바스크립트의 clearTimeout으로 이를 간단히 구현할 수 있다.

19째 줄에서 timer는 새로 생성된다.(timer값의 스코프가 할당)

timer는 0.4초 후에 콜백함수가 실행되는 setTimeout 비동기 함수이다.

우리는 사용자가 타이핑을 끝내고 난 뒤에 API 요청을 보내고 싶기 때문에,

18째 줄에서 이전에 할당한 timer(.4초 후에 API 요청을 보내는 콜백함수)를 clear해준다.

 

위 함수에서는 사용자가 입력 행위(input)를 더이상 반복하지 않을 때(끝낼 때) timer가 clear되지 않기 때문에 마지막 timer는 콜백함수를 실행하여 "api 요청"을 콘솔에 출력한다.

 

가시성을 위해 0.4초가 아닌 4초 후 alert하도록 변경하였다.

 

4초 후 api 요청 alert

 

clearTimeout을 하지않고 1초 후 alert를 실행하는 setTimeout을 timer에 할당하였을 때

만약 clearTimeout을 하지 않으면 위처럼 1초 후 alert하는 콜백함수가 차례대로 실행되고, alert창이 쌓인다.(API 요청이라면 API 요청이 쌓이고, 서버 측과 끊임없이 통신하게 된다)

 

이를 리액트에 적용해보면 어떨까?

적용을 위해 이전에 만든 gethub프로젝트 코드를 가져왔다.

 

원래는 submit 이벤트가 발생하면, Main 컴포넌트에 검색 결과를 띄우는데 이를 타이핑이 끝나면 바로 검색결과 api를 요청하려고 한다.

 

일단은 timer를 선언해 줘야 한다. 컴포넌트 내에서 사용할 것이므로 useState를 사용하여 변수로 관리한다.

 

이전 timer가 존재한다면, 해당 timer를 지워 api를 요청하는 콜백함수의 실행을 제거하고,

새로운 timer를 생성한다.(setTimer)

더 이상 timer의 생성이 일어나지 않으면, 사용자의 타이핑이 끝났다는 의미이므로 handleSubmit 함수를 호출해 api를 요청한다.

결과:  input값과 input값을 추적하고 있는 localState값은 onChange 이벤트가 일어날 때마다 호출되지만, api 요청은 마지막에 한 번 가는 것을 확인할 수 있다.