debounce (콤보박스)

ujin·2022년 11월 20일
0

개발

목록 보기
2/5

필요성

input창을 사용할 때 onChange 이벤트나 scroll 이벤트등 한번에 많이 일어나는 이벤트들을 처리하는 경우 최적화해줄 필요가 있기 때문이다.

인스타그램 클론 코딩에서 검색 부분을 맡았는데 Input을 입력 받아 해당 검색 결과에 맡는 유저만 보여줘야 하는 Search Input을 구현해야 했다. 사용자가 input에 입력 넣은 값에 따라 해당 리스트를 보여주어야하는데 사용자가 input을 언제 마무리 했는지에 대한 로직을 직접 예측하기는 무리여서 onKeyUp 이벤트를 사용하였다. 그러면 한글자 타이핑을 할때마자 해당 필터링 함수가 실행된다. 우리 프로젝트는 이벤트가 많이 발생하지 않아서 굳이 할 필요는 없었지만 그래도 해보면 좋을 거 같아서 debounce를 이용했다.

debounce란

특정 이벤트가 발생할 때에작동하는 비지니스 로직이 과도하게 발생하는 것을 방지하기 위하여 사용되는 함수이다. onChange() 함수를 통해 이벤트가 발생할 때마다 서버에 API를 호출하기보다는 일정 시간이 지난 후에 서버 API를 호출하게 되는 지연 호출의 역할을 하는 함수를 말한다. lodash.js 안에 있는 기능 중 하나이다.

*리액트에서는 lodash 라이브러리인 debounce 함수를 사용할 수 있다.

debounce 로직

  1. 입력 (Input: onKeyup Event)
  2. 주어진 시간동안 새로운 입력이 없는지 대기 (setTimeout)
  3. 새로운 입력이 없다면 매개변수로 받은 함수를 실행 (Callback Function)
  4. 새로운 입력을 받으면 기존 입력 취소 (clearTimeout)
function debounce (fn, duration) { // fn (콜백함수), duration(지연 시간)
  let timeout = null // settimeout 기본 함수가 들어갈 변수, 기본값 null
  return function (event) {
    clearTimeout(timeout)
    timeout = setTimeout(function () {
      fn(event)
      timeout = null
    }, duration)
  }

<input 
   onKeyUp={debounce(changeHandler, 1000)} 
   onChange={changeHandler} 
   onFocus={() => {setFocus(true)}}
/>

debounce 함수는 리턴한다.

debouncing은 연속된 이벤트 중 마지막 이벤트의 콜백함수만을 실행한다.

timeout이라는 함수에 closure 개념을 적용하여 setTime과 clearTimeout의 범위를 제한해주기 위해서이다.

그렇게 return 된 함수에는 debounce 즉, input Element의 event가 전달되어 argument로 넘어온다.

그리고 input에 텍스트를 치면 clearTimeout이 먼저 동작하면서 이전 setTimeout을 제거하거나 초기화한다. 그리고 다음줄로 넘어가setTimeout을 실행한다.

duration(지연시간) 만큼 지난후 fn이 실행되지만, duration 시간이 지나기 전에 또 다른 input 이벤트가 발생하면, clearTimeout때문에 다시 초기화 한다.

이게 반복되다가 duration의 시간만큼 동작이 없다면 그때 fn() 함수를 실행시킨다.

profile
개발공부일기

0개의 댓글