도서 검색 프로젝트에서는 키보드 입력시 검색 결과가 나오도록 구현했다. 키보드의 입력이 발생할때마다 리렌더링이 발생하여 한글자씩 키워드가 전달되어 API요청이 발생된다. 검색결과를 얻는 과정에서 한글자마다 api요청이 이루어진다면 불필요한 요청이 발생하는 것이고, 속도가 느려지고, 성능이 안좋아진다. 이를 해결하기 위한 방법으로 debounce가 있다. debounce를 사용하여 사용자가 키워드입력을 완료했을 시점에 API요청이 발생되도록 구현해보았다.
📍 debounce란?
이벤트나 함수들이 실행되는 빈도를 줄여서 성능을 좋게하는 방법이다. 특정시간 이전에 일어난 이벤트들을 그룹화하고, 특정시간이 지난 그 시점에 한번만 이벤트를 발생시킨다. 주로 과도한 이벤트가 일어나는 경우에 사용한다.
📍 debounce의 동작 원리
이벤트가 발생할때마다 타이머를 설정하고, 설정한 시간동안 이벤트가 발생하지 않으면 이벤트가 끝났다고 간주된다. 설정한 시간이전에 이벤트가 발생한다면 이전 타이머는 취소되고(clearTimeout(timer)) 새로운 타이머를 설정한다.
📍 구현
debounce를 이용하지 않았을 때
책이름을 입력 할 수 있는 input창을 만들어 입력 값을 console창에 입력해보았다.
export default function SearchVar() {
const onChange = (e) => {
console.log(e.target.value);
};
return (
<label>
책이름 :
<input type="text" name="book" onChange={onChange} />
</label>
);
}
결과와 같이 한자씩 콘솔에 찍한다. 입력창 값이 위의 값들을console로 출력되는 것이아닌 api로 호출된다면 불필요한 요청이 발생된다는 것을 알 수 있다.
debounce를 사용했을 때
export default function SearchVar() {
let [timer, setTimer] = useState();
const onChange = (e) => {
if (timer) { //timer가 존재한다면 clearTimeout을 실행한다. timer에는 timeoutID가 담겨있다.
clearTimeout(timer);
}
const newTimer = setTimeout(() => {
console.log(e.target.value);
}, 800);
//이벤트가 발생할때마다 setTimeout함수가 호출된다. 만약 0.8초가 다 지나기 전에 이벤트가 발생하면 clearTimeout으로 시간을 초기화한다.
setTimer(newTimer);
};
return (
<label>
책이름 :
<input type="text" name="book" onChange={onChange} />
</label>
);
}
📍 setTimeout함수
📍 clearTimeout함수