뉴히의 개발 로그
[TIL] 20230709 - Throttling & debouncing / lodash 라이브러리 본문
[ Throttling ]
Leading Edge : 이벤트가 일어난 첫번째에 function을 일으킴
Trailing Edge : 이벤트가 일어났을 때 어느정도 Delay를 두고 마지막에 function을 일으킴
Leading & Trailing Edge : dealy의 처음과 마지막에 function을 일으킴
const throttle = (delay) => {
if (timerId) {
// timerId가 있으면 바로 함수 종료
return;
}
setState(!state);
console.log(`API요청 실행! ${delay}ms 동안 추가요청 안받음`);
timerId = setTimeout(() => {
console.log(`${delay}ms 지남 추가요청 받음`);
timerId = null;
}, delay);
};
[ debouncing ]
짧은시간 계속해서 이벤트를 발생시키면 이벤트 핸들러를 호출하지 않고 있다가 마지막이벤트로부터 일정시간 지난 후 이벤트를 한번만 호출
ex)입력값 실시간 검색, 화면 resize 이벤트
// 반복적인 이벤트 이후, delay가 지나면 funciton
const debounce = (delay) => {
if (timerId) {
clearTimeout(timerId);
}
timerId = setTimeout(() => {
console.log(`마지막 요청으로부터 ${delay}ms지났으므로 API요청 실행!`);
timerId = null;
}, delay);
};
[ 메모리 누수 ]
메모리 누수란 페이지 이동전에 setTimeout으로 인해 타이머가 작동중인 상태에서 페이지 이동이 일어났을시, clearTimeout이 안된상태에서 페이지 이동으로 컴포넌트는 언마운트 되었지만 setTimeout 타이머는 메모리를 차지하고 동작하고 잇는 경우.
=> useEffect에 return문으로 언마운트 될때 ~해달라 요청이 가능. return에 clearTimeout으로 메모리 지워주면됨
useEffect(() => {
return () => {
// 언마운트 시 (home이라는 컴포넌트가 사라질때 어떠한 동작 가능)
if (timerId) {
clearTimeout(timerId);
}
};
}, []);
[ debounce -> lodash 라이브러리 사용하기 ]
패키지 설치
yarn add lodash
디바운스 코드
// lodash 없이 구현
const debounce = (callback, delay) => {
let timerId = null;
return (...args) => {
// 클로저 함수, 외부 timerId를 참조
if (timerId) clearTimeout(timerId);
timerId = setTimeout(() => {
callback(...args);
}, delay);
};
};
const handleSearchText = useCallback(
debounce((text) => {
setSearchText(text);
}, 2000),
[]
);
// 디바운싱 lodash 사용
const handleSearchText = useCallback(
_.debounce((text) => {
setSearchText(text);
}, 2000),
[]
);
debounce 할때는 useCallback 으로 메모이제이션 해줘야함
렌더링이 다시 일어나도 새롭게 함수가 리턴되는게 아니라 이전을 기억하고 그대로 적용가능
ex. 타자를 쳤을때 하나씩 따라오는게 아니고 단어단위로 setState됨