가끔 그럴 일이 있다. 스크롤을 막아야 하는데 스크롤 바 까지 지우면 안되고, 휠을 내리거나 올렸을 때는 스크롤이 막히지만, 스크롤 바를 클릭해서 움직이면 스크롤이 이동해야 하는. 정말 그럴 일이 있냐고? 있을 수도 있지.
보통 스크롤을 막을땐 body의 css 속성을 건드리는 경우가 많다. 그런데 body의 overflow를 hidden으로 설정하면 스크롤바 역시 함께 사라진다. 어떻게 해야 할까?
제일 직관적으로 떠오르는 것은 wheel 이벤트를 막는것이다.
function wheelEvent(e: React.WheelEvent) {
e.preventDefault();
}
preventDefault 함수를 사용해 이벤트의 기본 동작을 막고
<div onWheel={wheelEvent}>
휠 이벤트가 발생할 부분에 이렇게 붙이면 될 것이다. 그런데 원하는 대로 작동하지 않는다.

이유가 무엇일까? 이유는 바로 wheel 이벤트의 passive 옵션이 true로 설정되어 있기 때문이다. 자세한 내용은 이곳 참고
그렇다면 wheel 이벤트의 passive 옵션을 false로 변경해서 등록해 줘야 하는데, 문제는 리액트의 합성 이벤트는 passive 옵션을 받지 않는다. 그렇다면 어떻게 해야 할까?
useEffect(() => {
window.addEventListener("wheel", wheelEvent, { passive: false });
return () => {
window.removeEventListener("wheel", wheelEvent);
};
}, []);
별수 있나. useEffect를 통해 컴포넌트가 마운트될때 직접 등록해 주는 수 밖에.
이방법으로 함수를 등록할 때 함수 안에서 state를 계속 추적해야 한다면 useEffect의 뎁스 배열 [ ] 에 state를 등록해 주어야 한다.
useEffect(() => {
window.addEventListener("wheel", wheelEvent, { passive: false });
return () => {
window.removeEventListener("wheel", wheelEvent);
};
}, [state]);
이렇게 말이다.