Using React Hooks To Update w/ Scroll
Or you can use window.pageYOffset. It's a bit more understandable for me that way:
const [scrolling, setScrolling] = useState(false);
const [scrollTop, setScrollTop] = useState(0);
useEffect(() => {
function onScroll() {
let currentPosition = window.pageYOffset; // or use document.documentElement.scrollTop;
if (currentPosition > scrollTop) {
// downscroll code
setScrolling(false);
} else {
// upscroll code
setScrolling(true);
}
setScrollTop(currentPosition <= 0 ? 0 : currentPosition);
}
window.addEventListener("scroll", onScroll);
return () => window.removeEventListener("scroll", onScroll);
}, [scrollTop]);
You're missing the dependencies in your hook. Try this:
useEffect(() => {
const onScroll = e => {
setScrollTop(e.target.documentElement.scrollTop);
setScrolling(e.target.documentElement.scrollTop > scrollTop);
};
window.addEventListener("scroll", onScroll);
return () => window.removeEventListener("scroll", onScroll);
}, [scrollTop]);
By moving onScroll
inside the useEffect
, you don't need to track it on the hook's dependencies, however since it uses scrollTop
from the component's scope, you'll need to add it.
Alternatively, if for some reason you don't want to move onScroll
definition inside the useEffect
, you'll need to wrap onScroll
in useCallback
and track it in useEffect
's dependency array.
In general I'd recommend adding react-hooks/exhaustive-deps
to your ESlint rules
Also it's a good idea to remove the event listener in cleanup function.