FrontEnd/React
useEffect 내에서 eventListener 설정 시 동작하는 원리
Bumang
2024. 2. 15. 12:43
오늘 만든 resize 이벤트가 끝나면 0.5초 이후 true값을 반환하는 useCatchResizeEnd 훅.
import { useEffect, useState } from 'react';
export const useCatchResizeEnded = () => {
const [isEnded, setIsEnded] = useState(false);
useEffect(() => {
let resizeTimeout: NodeJS.Timeout;
setIsEnded(false);
const handleResize = () => {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => {
console.log('timeout이 멈췄습니다.');
setIsEnded(true);
}, 500);
};
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return [isEnded];
};
useEffect내에 의존성 배열을 비워뒀다.
순간 의존성배열이 없으면 mount될 때 한 번 실행되니
resize이벤트가 계속 발생해도 캐치 못하는게 아닌지 고민했다.
그러나 첫 mount 때 addEventListener를 등록 한 번 하면, 계속 resize를 listening하고있는 상태는 유지된다.
그리고 unmount될 때 클린업 함수가 실행되서 resize 리스너를 제거한다.
오히려 의존성 배열에 어떠한 상태를 넣었는데 그게 계속 업데이트되면
업데이트 될 때마다 useEffect내의 클린업 함수를 실행하고 다시 이벤트 리스너를 재등록하게 되기 때문에,
한 번 이벤트 리스너를 등록해두고 페이지를 이탈하기 전까지 쭈욱 유지하고 싶으면
의존성 배열을 비워두는 것이 좋다.
결과적으로 0.5초 이후 값이 바뀌는 isEnded로 throttle 비슷한 효과를 내며 불필요한 렌더를 방지할수 있다.