Infinite Scrolling is highly trending as an interaction behavior on pages and lists. The basic functionality is that, as the user scrolls through content, more content is loaded automatically. With the popularity of social media, massive amounts of data are being consumed, Infinite Scrolling offers an efficient way to browse that ocean of information, without having to wait for pages to preload. Rather, the user enjoys a truly responsive experience, whatever device they’re using.
Demo
Getting Started
We will be implementing Infinite Scroll in a React Project. Set up a React Project before continuing.
We need to use ref to store the reference to the last element for Infinite Scroll.
Creating the App component.
constMAX_PAGES=5;constApp=()=>{const[items,setItems]=React.useState([]);const[isLoading,setIsLoading]=React.useState(false);const[hasMore,setHasMore]=React.useState(true);const[pages,setPages]=React.useState(0);constobserver=React.useRef();React.useEffect(()=>{// generating the 1st page on Component MountingupdateItems();setPages((pages)=>pages+1);},[]);constlastItemRef=React.useCallback((node)=>{// ensuring redundant calls are not made once the data is already BEING updatedif (isLoading)return;if (observer.current)observer.current.disconnect();observer.current=newIntersectionObserver((entries)=>{if (entries[0].isIntersecting&&hasMore){if (pages<MAX_PAGES){// adding more data only if:// 1. MORE data exists ("hasMore" - simulated with "pages < MAX_PAGES")// 2. the last item is visible on the screen (using the "IntersectionObserver")updateItems();setPages((pages)=>pages+1);}else{setHasMore(false);}}});if (node)observer.current.observe(node);},[isLoading,hasMore]);constupdateItems=async ()=>{setIsLoading(true);// simulating asynchronous nature of api (which is the general use case for Infinite Scroll)awaitnewPromise((resolve)=>setTimeout(resolve,1000));setItems((currItems)=>{constlastItem=currItems.length;constupdatedItems=[...currItems];for (leti=1;i<=5;i++){constitem=lastItem+i;updatedItems.push(item);}returnupdatedItems;});setIsLoading(false);};return (<React.Fragment><h1>InfiniteScrollDemo</h1>
{items.map((item,index)=>index+1===items.length?(<Itemreference={lastItemRef}key={index}>{item}</Item>
):(<Itemkey={index}>{item}</Item>
))}{isLoading&&<divclassName="loader"/>}</React.Fragment>
);};
Update
As pointed out by some people in the comments, it can lead to performance degradation, so its suggested that when using infinite scroll for large list of items (around 250+ items), you should create the following CSS class:
.hidden{visibility:hidden!important;}
and add it to your items when they are not in the viewport.