scroll을 아래로 내릴 때, header가 안보이게 되어야 한다. scroll을 위로 하면, header가 다시 보여야 한다.
// page
const Page = () => {
// scroll이 일어나는 container. 현재 scroll 내린 만큼의 값을 구하기 위해
const scrollContainerRef = useRef(null)
// 과거의 scroll 값 저장 위해서
const scrollRef = useRef(0)
// 현재 scrollTop 지정
useEffect(() => {
if (scrollContainerRef.current) {
scrollRef.current = scrollContainerRef.current.scrollTop;
}
}, [scrollContainerRef.current]);
const handleScroll = () => {
const prevScroll = scrollRef.current;
// scrollTop : distance from the element's top to its topmost visible content
const currentScroll = e.target.scrollTop;
if(prevScroll > currentScroll){
console.log('go down')
} else {
console.log('go up')
}
// 현재 값을 넣어서 다음 scroll handle에서 이전 값으로 쓰게
scrollRef.current = currentScroll;
}
return (
<PageContainer onScroll={handleScroll} ref={scrollContainerRef} >
<></>
</PageContainer>
);
}
go down
, go up
에서 state true, false를 정해주어서 header의 표시를 정해주면 된다.
위 코드로도 작동은 잘 하지만, 조금의 scroll event에도 마치 발작하듯이 무수히 많은 console.log의 요청(?)이 쏟아질 것이다. lodash
라이브러리의 throttle
함수를 사용해서 이를 조금 줄여보려고 한다.
throttle : 'n초에 한 번 작동'의 개념으로 받아들이면 이해가 쉽다.
handleScroll
안의 로직 부분을 따로 분리하여 throttle을 걸어주려고 한다.
const handleScroll = () => {
const prevScroll = scrollRef.current;
const currentScroll = e.target.scrollTop;
/* 이부분을 들어내줄 것이다 */
if(prevScroll > currentScroll){
console.log('go down')
} else {
console.log('go up')
}
scrollRef.current = currentScroll;
/* 이부분을 들어내줄 것이다 */
}
useMemo
를 사용해서 throttle을 건 함수를 만들어준다. (굳이 useMemo가 아니더라도 상관없을 것 같다. 그냥 함수여도 되고, useCallback을 사용해도 괜찮을 것 같다.) const throttledScroll = useMemo(
(prevScroll, currentScroll) =>
throttle((prevScroll, currentScroll) => {
if (prevScroll > currentScroll) {
//console.log('go down');
setHide(() => false);
} else {
//console.log('go up');
setHide(() => true);
}
scrollRef.current = currentScroll;
}, 200),
[],
);
const handleScroll = e => {
const prevScroll = scrollRef.current;
const currentScroll = e.target.scrollTop;
throttledScroll(prevScroll, currentScroll);
};
throttle
안에 함수가 () => 들어가야한다는 것만 계속 인지하면 쉽게 해결할 수 있는 문제였다. https://www.w3schools.com/howto/howto_js_navbar_hide_scroll.asp