const shouldHide = useHideOnScroll();
return shouldHide ? null : <div>something</div>
The useHideOnScroll behaviour should return updated value not on every scroll but only when there is a change.
The pseudo logic being something like the following:
if (scrolledDown && !isHidden) {
setIsHidden(true);
} else if (scrolledUp && isHidden) {
setIsHidden(false);
}
In words, if scroll down and not hidden, then hide. If scroll up and hidden, then unhide. But if scroll down and hidden, do nothing or scroll up and not hidden, do nothing.
How do you implement that with hooks?
After hours of dangling, here is what I came up with.
Usage:
It's still suboptimal, because we reassign the
onScroll
when theisHidden
changes. Everything else felt too hacky and undocumented. I'm really interested in finding a way to do the same, without reassigningonScroll
. Comment if you know a way :)You need to use window.addEventListener and https://reactjs.org/docs/hooks-custom.html guide.
That is my working example:
live demo: https://codesandbox.io/s/w0p3xkoq2l?fontsize=14
and i think name
useIsScrolled()
or something like that would be betterHere:
You might have concern about
setIsHidden
causing rerender on everyonScroll
, by always returning some new state value, but a setter fromuseState
is smart enough to update only if the value has actually changed.Also your
.navbar
(I've added a class to it) shouldn't change the layout when it appears or your snippet will get locked in an infinite loop. Here're appropriate styles for it as well:Full CodeSandbox: https://codesandbox.io/s/13kr4xqrwq