// 스크롤이 내려가고 올라오는지 확인해주는 핸들러 const handleScroll = useCallback( (e) => { // 현재위치와 이전 위치의 차를 계산한다. const diff = e.target.scrollTop - prevY if (diff > 0) { console.log('내려가는중') // 헤더를 보여줄지 말지 set setIsHeaderShow(false) } else if (diff < 0) { console.log('올라가는중') setIsHeaderShow(true) } setPrevY(e.target.scrollTop) }, [prevY] ) // 스크롤이 멈췄는지 확인해주는 핸들러 const stopScroll = useCallback((e) => { console.log('🥎🥎🥎멈춤', e.target.scrollTop) // 스크롤이 가장 끝까지 올라가면 헤더보임. // 스크롤이 멈추면 헤더안보임 if (e.target.scrollTop === 0) { setIsHeaderShow(true) } else { setIsHeaderShow(false) } }, []) // 스크롤의 위 아래 이동감지는 쓰로틀이 이용 const throttleScroll = useThrottle(handleScroll, 300) // 스크롤의 멈춤은 디바운스를 이용한다.(디바운스가 마지막 그룹의 이벤트를 노티해준다는 특성이용) const debounceScroll = useDebounce(stopScroll, 1500) const scrollDetectHandler = useCallback( (...e) => { throttleScroll(...e) debounceScroll(...e) }, [prevY] ) // DOM 제어시 useLayoutEffect를 사용하는게 성능상 좋음. useLayoutEffect(() => { if (scrollRef.current) { scrollRef.current.addEventListener('scroll', scrollDetectHandler) } return () => { if (!scrollRef.current) return scrollRef.current.removeEventListener('scroll', scrollDetectHandler) } }, [prevY])