visit
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
const [isBottom, setIsBottom] = useState(false);
const scrollTop = (document.documentElement
&& document.documentElement.scrollTop)
|| document.body.scrollTop;
const scrollHeight = (document.documentElement
&& document.documentElement.scrollHeight)
|| document.body.scrollHeight;
if (scrollTop + window.innerHeight + 50 >= scrollHeight) {
setIsBottom(true);
}
function handleScroll() {
const scrollTop = (document.documentElement
&& document.documentElement.scrollTop)
|| document.body.scrollTop;
const scrollHeight = (document.documentElement
&& document.documentElement.scrollHeight)
|| document.body.scrollHeight;
if (scrollTop + window.innerHeight + 50 >= scrollHeight){
setIsBottom(true);
}
}
Now that we have used our Hook to set the new state for our isBottom state, we need to create a Hook that will trigger on any update of this variable, so let's do that:
useEffect(() => {
if (isBottom) {
addItems();
}
}, [isBottom]);
So we are using a useEffect Hook that updates with every change of the isBottom state. We are setting this with the brackets after the callback function. Anything inside the brackets is what the Hook will listen to, to know it is time to update.
Inside we will only care if we are at the bottom of the page to trigger the fetching/adding of new items if the change of state turned it into false, that means that we got far from the bottom and we don't want to trigger the function.And that is pretty much it! You now have a fully functional infinite scroll built from scratch. Now you can create the addItems function to work exactly as you need it. The only thing to consider is that after doing whatever you need to do, you need to reset the state of isBottom to false.
In my case, I had a list of stocks (over 14,000), and I wanted to display 30 by 30, so I set the state of my variable here and then reset the isBottom. This is what my addItems function looks like:
const addItems = () => {
if (state.stocks.length !== 0) {
setStocksToDisplay(prevState => ({
page: prevState.page + 1,
stocksToDisplay: prevState.stocksToDisplay.concat(
state.stocks.slice(
(prevState.page + 1) * 30,
(prevState.page + 1) * 30 + 30,
),
),
}));
setIsBottom(false);
}
};
The only important thing of this function for you is the reset to false part of the isBottom function, but I wanted to show you a complete implementation. I hope you find this useful, and if you have any other questions, I am always available through , , or .
See you on the other side!Happy coding!