What is Infinite Scroll?
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.
Implementing Infinite Scroll
First let's add the Item
component.
const Item = ({ children, reference }) => {
return (
<div ref={reference}>
{children}
</div>
);
};
We need to use ref
to store the reference to the last element for Infinite Scroll.
Creating the App
component.
const MAX_PAGES = 5;
const App = () => {
const [items, setItems] = React.useState([]);
const [isLoading, setIsLoading] = React.useState(false);
const [hasMore, setHasMore] = React.useState(true);
const [pages, setPages] = React.useState(0);
const observer = React.useRef();
React.useEffect(() => {
// generating the 1st page on Component Mounting
updateItems();
setPages((pages) => pages + 1);
}, []);
const lastItemRef = React.useCallback(
(node) => {
// ensuring redundant calls are not made once the data is already BEING updated
if (isLoading) return;
if (observer.current) observer.current.disconnect();
observer.current = new IntersectionObserver((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]
);
const updateItems = async () => {
setIsLoading(true);
// simulating asynchronous nature of api (which is the general use case for Infinite Scroll)
await new Promise((resolve) => setTimeout(resolve, 1000));
setItems((currItems) => {
const lastItem = currItems.length;
const updatedItems = [...currItems];
for (let i = 1; i <= 5; i++) {
const item = lastItem + i;
updatedItems.push(item);
}
return updatedItems;
});
setIsLoading(false);
};
return (
<React.Fragment>
<h1>Infinite Scroll Demo</h1>
{items.map((item, index) =>
index + 1 === items.length ? (
<Item reference={lastItemRef} key={index}>
{item}
</Item>
) : (
<Item key={index}>
{item}
</Item>
)
)}
{isLoading && <div className="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.
Projects using this Implementation
Smartsapp (Previous Messages on scroll up)
Web-app: https://smartsapp-ba40f.firebaseapp.com
ruppysuppy / SmartsApp
๐ฌ๐ฑ An End to End Encrypted Cross Platform messenger app.
Smartsapp
A fully cross-platform messenger app with End to End Encryption (E2EE).
Demo
NOTE: The features shown in the demo is not exhaustive. Only the core features are showcased in the demo.
Platforms Supported
- Desktop: Windows, Linux, MacOS
- Mobile: Android, iOS
- Website: Any device with a browser
Back-end Setup
The back-end of the app is handled by Firebase
.
Basic Setup
- Go to firebase console and create a new project with the name
Smartsapp
- Enable
Google Analylitics
App Setup
- Create an
App
for the project from the overview page - Copy and paste the configurations in the required location (given in the readme of the respective apps)
Auth Setup
- Go to the project
Authentication
section - Select
Sign-in method
tab - Enable
Email/Password
andGoogle
sign in
Firestore Setup
- Go to the project
Firestore
section - Create firestore provisions for the project (choose the server nearest to your location)
- Go to the
Rules
โฆ
Pizza Man (Previous Orders on scroll down)
Web-app: http://pizza-man-61510.firebaseapp.com/
ruppysuppy / Pizza-Man
๐๐ An e-commerce website to order pizza online
Pizza Man Project
An E-Commerce website for ordering Pizza Online
Demo
NOTE: The features shown in the demo is not exhaustive. Only the core features are showcased in the demo.
Tools used
- React: To create the Single Page App
- React-Router: For Routing
- Redux: For State Management
- Firebase: As a DataBase
Firebase Setup
You need to create a firebase configeration file holding the firebase settings in the path /src/firebase/config.js
. The required format is:
const firebaseConfig = {
apiKey: "API-KEY",
authDomain: "AUTH-DOMAIN.firebaseapp.com",
databaseURL: "DATABASE-URL.firebaseio.com",
projectId: "PROJECT-ID",
storageBucket: "STORAGE-BUCKET.appspot.com",
messagingSenderId: "MESSAGING-SENDER-ID",
appId: "APP-ID",
measurementId: "MEASUREMENT-ID",
};
export default firebaseConfig;
Data needs to be stored in the following format:
[
{
name: "CATEGORY NAME",
items: [
{
desc: "PIZZA DESCRIPTION",
id: "ID",
img: "IMAGE LINK",
name
โฆFinding personal finance too intimidating? Checkout my Instagram to become a Dollar Ninja
References
YouTube
Smashing Magazine
Thanks for reading
Reach out to me on:
Top comments (6)
This is a lazy, and bad way to implement it. Continually adding stuff to the bottom of the page for an 'infinite' scroll is a sure-fire way to slow the browser down and eat memory. You should also remove items from the top that have scrolled out of view, and readjust accordingly
I totally agree that not removing the items from the top that have scrolled out of view eats away at the memory, but its not feasible in most use cases, especially where the data is dynamic like Facebook (FB doesn't implement this feature either).
Yes it does.
1 page on Facebook:
10 pages on Facebook:
This is a horrible way to implement infinite scrolling and youโll get crippling performance issues with a decently large list. You should use something like react-window
I stand rectified, Facebook doesn't un-render the contents, but it does hide them to improve performance