Add Infinite Scroll in MERN Stack

Hamza Aziz
3 min readAug 8, 2024

--

Understanding Infinite Scroll

While using YouTube or any other social media platform you would notice that when you keep scrolling down, at one stage you see a loader such as the one shown in image below

After this loading is completed you see more videos, posts or content and in this way you keep on scrolling. This feature does not require any user input. They automatically get served with more and more content upon scrolling. This is what we call Infinite Scroll.

This is a great feature for User Experience (UX) and a wonderful alternative of pagination (in which users themselves have to click next and previous buttons to load content).

As a developer, you can add this feature in your application to massively enhance the UX.

Implementation in MERN Stack

For adding Infinite Scroll in your MERN project you need configuration in both backend and frontend. Lets start with the backend first.

Setup a basic express and node backend, then install all necessary packages such as mongoose, express and cors.

Now create a model which we will use in our project. Here I am using a basic model named Product (you can have one according to your choice).

import { Schema, model } from "mongoose";

const productSchema = new Schema({
name: { type: String, required: true },
price: { type: Number, required: true },
});

const Product = model("Product", productSchema);
export default Product;

Afterwards, initialize MongoDB for this project. Then after starting your app with express, cors and other configuration use below code

app.get('/', async (req, res) => {
try {
const page = parseInt(req.query.page) || 1;
const limit = parseInt(req.query.limit) || 5;
const skip = (page - 1) * limit;

const products = await Product.find().skip(skip).limit(limit)
res.json(products)
} catch (error) {
res.status(500).json({ message: error.message })
}
})

You would notice we are using page, limit and skip here. Here we are using 5 products per page, meaning first send five products, then on new request send five more products and so on. Each page represents the request number we are sending, limit is the maximum number of posts we will send and skip tells us which products to skip on each request (for example on second request, skip first five products. On third request, skip first ten products and so on).

Now let’s cover the frontend part for which you need to setup you react project first. Then install axios (you can use fetch if you want) and react-infinite-scroll-component which you can get at this link below

After this go to the page or component in which you want to have infinite scroll functionality. I named it Home, you can name as per your choice. In it am using following code:

import React, { useState, useEffect } from 'react'
import InfiniteScroll from 'react-infinite-scroll-component';
import axios from 'axios';

const Home = () => {
const [products, setProducts] = useState([])
const [hasMore, setHasMore] = useState(true)
const [page, setPage] = useState(1)

useEffect(() => {
fetchData()
}, []) // [] to only run once on component mount

const fetchData = () => {
axios.get(`http://localhost:4000?page=${page}&limit=5`)
.then(response => {
setProducts([...products, ...response.data])
console.log(response.data)
setHasMore(response.data.length > 0)
setPage(page + 1)
})
.catch(error => console.log(error))
}

const fetchMoreData = () => {
fetchData()
}

return (
<div>
<h1>All Products</h1>

<InfiniteScroll
dataLength={products.length}
next={fetchMoreData}
hasMore={hasMore}
loader={<div className="loader">Loading...</div>}
>
{
products.map((product) => (
<div key={product._id} className='product'>{product.name}</div>
))
}
</InfiniteScroll>
</div>
)
}

export default Home

Note that I am using localhost in my axios URL as my backend is running at localhost port 4000. You should add the one you are using and keep it in .env file.

You can also add the CSS or styling you desire.

That is it. Now you have a MERN Stack application which features infinite scroll. If you face any issue at any stage, head over to this GitHub repo by me at the link below:

--

--

Hamza Aziz
0 Followers

Full Stack Website Developer & Data Analyst