How to Implement Pagination in MERN-Stack Applications
Tags: webdev, javascript, react, node
Published: 2024-02-15 14:56:43

Pagination isn’t just about aesthetics. It is crucial for user experience and performance. Pagination breaks down information into digestible chunks, making it easier for users to navigate, find what they need quickly, and avoid information overload. It's a win-win for both sides: users appreciate the faster loading times and focused content, while websites benefit from improved performance, better SEO due to unique content on each page, and ultimately, a happier user experience.

In this guide, we'll learn how to add pagination to a MERN stack project. That's using React.js for the front-end, which talks to the back-end Express APIs. As the database, We'll use MongoDB, and Node.js for handling back-end tasks, to make a user-friendly pagination system. To do data fetching, we’ll use [Axios](https://axios-http.com/docs/example) and [TanStack Query](https://tanstack.com/query/latest/docs/framework/react/quick-start). When we're done, you'll grasp how to set up and use pagination effectively.

## Front-end (React.js)
We will create states to deal with the currently selected page and to store the total amount of page data that is coming from the back-end. At the initial stage, the currently selected page will be ‘1’.

```javascript
    const [currentPage, setCurrentPage] = useState(1);
    const [totalPageAmount, setTotalPageAmount] = useState(0);

    //Fetch data using Axios and TanStack
    const { isPending: paginatedDataPending, data: paginatedData } = useQuery({
        queryKey: ["paginated-data", currentPage],
        queryFn: async () => {
            const res = await axios.get(`local-host-address/paginatedDataApi?dataPerPage=10&currentPage=${currentPage}`) //Here, I'm assuming I want 10 data in a single page. That’s why I used dataPerPage = 10
            setTotalPageAmount(res.data.totalPages);
            return res.data.paginatedData;
        }
    })

    //To avoid any error, we will use a conditional loading
    if (paginatedDataPending) {
        return <p>Loading…</p>
    }


    //Here, ‘totalPageAmount’ is a number. So, we have to turn it into an array, so that we can use the map function.
    const totalPages = [...Array(totalPageAmount).keys()];
```

Now in JSX, we will use a pagination bar, so that we can select our desired page.

```javascript
        //Pagination element in JSX
        <div>
            {
                totalPages.map(page =>
                    <button key={page}
                        onClick={() => setCurrentPage(page + 1)}>
                        {page + 1}
                    </button>)
            }
        </div>
```

Feeling a bit lost? No worries, it's because we haven't dealt with the back-end stuff yet. So, let's clear up the confusion and switch our focus to the back-end. We're about to simplify things and make it all less puzzling. Ready to check out what's happening behind the scenes? Let's get started!

## Back-end (Node.js, Express.js, and MongoDB)
Here is where the magic happens. To craft our API, we'll be utilizing Express.js, as mentioned earlier. So, let's delve into the details and witness the behind-the-scenes work unfold.

```javascript
//Get paginated result
app.get("/paginatedDataApi", async (req, res) => {

    //Get query result
    const dataPerPage = parseInt(req.query.dataPerPage);
    const currentPage = parseInt(req.query.currentPage);

    //Get data from database
    const totalData = await databaseCollectionName.find().toArray();

    //Pagination calculation
    const totalPages = Math.ceil(totalData.length / dataPerPage) //calculating total pages
    const startIndex = (currentPage - 1) * listingPerPage;
    const endIndex = currentPage * listingPerPage;
    const paginatedData = totalData.slice(startIndex, endIndex); //getting the paginated result only to send to the front-end

    //Send the result to front-end
    res.send({ totalPages, paginatedData });
})
```

Voila! Our pagination system is up and running smoothly. Easy peasy, wasn't it? We've got this!

## Conclusion
In a nutshell, adding this sturdy pagination system makes MERN apps way better for users. It helps handle a bunch of data more smoothly and shows it in a way that's easier for everyone to use. Cool, right?

Follow me on: [Github](https://github.com/nahidul-fahim) [LinkedIn](https://www.linkedin.com/in/iamnahidul-islam)