react에서 Header에 스크롤 이벤트를 해봤다.
const [showHeader, setShowHeader] = useState(true);
useEffect(() => {
window.addEventListener("scroll", handleScroll);
}, []);
const handleScroll = () => {
const currentScrollPosition = window.pageYOffset;
if(currentScrollPosition > 100) {
setShowHeader(false);
} else {
setShowHeader(true);
}
}
return (
<HeaderContainer style={{ display: showHeader ? 'block' : 'none' }}>
{/* 헤더 내용 */}
</HeaderContainer>
);
나는 react에서 header에 스크롤 이벤트를 적용해보는 것은 처음인지라,
처음에 위와 같이 짜고 chatGPT에게 물어봤다.
그랬더니 아래 코드와 같이 수정해줬다.
useEffect(() => {
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, []);
useEffect안에 리턴을 써서 스크롤 이벤트를 제거해주는 함수를 썼다.
나는 왜 이렇게 해야하는 지 몰랐다.
실제로 스크롤 이벤트를 제거해주는 함수를 적어주지 않아도 작동이 잘 됐기 때문이다.
그래서 왜 저 return 을 적어줘야하는지에 대해서, 그리고 안적어주면 어떤지에 대해 물었다.
useEffect return함수는 cleanup 함수라고 한다.
컴포넌트가 unmount되거나 업데이트 될 때 실행된다고 했다.
return문은 등록한 이벤트 핸들러를 unmount될때 제거하기 위해서 사용하는 것이고,
불필요한 리소스 사용을 막아준다고 한다.
만약 unmount될 때 cleanup 함수를 반환하지 않는다면
이벤트 핸들러의 등록이 해제되지 않아 메모리 누수가 발생할 수 있다고 설명했다.
제거되지 않은 핸들러가 쌓이다 보면 성능 이슈가 발생할 수 있다고 설명했다.
이런 부분은 처음 알았고, 화면에 구현만 되고 작동만 잘 된다면 아무 문제 없다고 생각했기 때문에
별로 신경쓰지 않았던 부분이었다.
이제 이런 것들을 알았으니 고려하며 코드를 짤 수 있을 것 같다.
그렇다면 아래와 같이 showHeader 값이 바뀔 때만 이벤트를 등록해주면 이벤트 함수 제거를 안써줘도 되지 않냐고 물어봤다.
useEffect(() => {
window.addEventListener("scroll", handleScroll);
}, [showHeader]);
이 방식은 값이 변경될 때마다 이벤트 핸들러를 등록하고 해제해줘야하기 때문에 그 과정에서 성능 저하가 발생할 수 있다고 답변해줬다.
스크롤 이벤트 등록은 마운트 될 때 한번만 실행해주고, unmount될 때 해제해주는 것이 좋은 방법이라고 한다. 따라서 useEffect를 빈 배열로 두는 것이 좋다고 해줬다.