https://javascript.plainenglish.io/hiding-dom-elements-in-react-based-on-scrolling-d9a9ef1f1f5
In frontend development, we often come across cases where we need to show/hide elements based on the level of scrolling. Here, I’m going to talk about two ways to achieve this using React. Firstly, implementing it ourselves, and secondly using an already available npm package.
1. Implementation
Consider an HTML element like:
<div id="hide">Content hidden when scrolled beyond 1000px</div>
To hide this in React, we’d need to conditionally render this div, based on the scroll level, for which the most logical choice is to use a *state variable*, which keeps track if the element must be visible or not. We can achieve this using the *useState* hook.
const [isVisible, setIsVisible] = useState(true);
And use this variable to *conditionally render* the div, like so:
{
isVisible
&&
<div id="hide">Content hidden when scrolled beyond 1000px</div>
}
Now, all that’s left, is to make the variable, track the scroll levels and find out if the element must be shown or hidden. We can carry this through by adding an *event listener* to track scroll, which must be added on component mount, and removed on component unmount.
For this we use the *useEffect* hook, to add event listener, with a blank dependancy array, which returns a function, that performs our clean-up during un-mounting (i.e, remove the event listener).
useEffect(() => {
window.addEventListener("scroll", listenToScroll);
return () =>
window.removeEventListener("scroll", listenToScroll);
}, [])
Now our mounting and un-mounting functions are complete, to add and remove the scroll event listener. We’re at our final and most important step now, which is defining the *listenToScroll()* function, which we added as listener function in previous step.
const listenToScroll = () => {
let heightToHideFrom = 1000;
const winScroll = document.body.scrollTop ||
document.documentElement.scrollTop;
if (winScroll > heightToHideFrom) {
isVisible && // to limit setting state only the first time
setIsVisible(false);
} else {
setIsVisible(true);
}
};
Thus, now our isVisible variable will track if the div must be shown or hidden. The entire thing will look like this:
There could also be cases where, you might want to hide an element when it reaches a div, for this all you need to do is alter the *heightToHideFrom* variable in *listenToScroll().*
const heightToHideFrom =
getOffset(document.querySelector("#your-div-id")
The *getOffset()* function used above hasn’t been defined yet, but its function is simply to get you the top offset from the bounding rectangle of the div you want, which can be implemented like so:
const getOffset = (element) => {
const rect = element?.getBoundingClientRect(),
scrollTop =
window.pageYOffset || document.documentElement.scrollTop; return rect!.top + scrollTop;
};
You can play around with these methods, and hide/show any element you want in React with ease, for any given scenario!
2. NPM Package
In practicality, it’s just unnecessary re-invention of the wheel, to write components for your hiding/showing elements for every project you work on. Here is where prebuilt packages come in handy.
That’s why I’ve built the package, *react-hide-on-scroll*, which has many utility components which provide functionalities for most scenarios, like hiding/showing between a specific height range, from a specific height, between, or from specific divs, or based on the direction of scroll, and so on.
For example, instead of writing all that code to achieve what we did in the previous example, to hide a div when scrolled beyond 1000px, we could simply do:
<HideOn atHeight height={1000}>
<div id="hide">Content hidden when scrolled beyond 1000px</div>
</HideOn>