Pagination in React, Node.js and MongoDB
In this tutorial, we will show you, how you can do pagination in your React app having Node.js and MongoDB as backend. Even if you have any other backend technology, you can still get the algorithm and apply it in your language.
React
Following is our React component that will call an AJAX request and fetch the data from API. After fetching the data from API, it will render the data along with the pagination links. Whenever any of the pagination link is clicked, it will refetch the data based on the clicked page number.
<script src="js/babel.min.js"></script>
<script src="js/react.development.js"></script>
<script src="js/react-dom.development.js"></script>
<div id="app"></div>
<script type="text/babel">
function App() {
// Set current page
const [page, setPage] = React.useState(1);
// Number of pages on pagination
const [pages, setPages] = React.useState(0);
// Whenever it's value is updated, the data will be re-fetched
const [refetch, setRefetch] = React.useState(0);
// Data array
const [users, setUsers] = React.useState([]);
// Check if there are more pages
const [hasMorePages, setHasMorePages] = React.useState(false);
async function loadMore() {
// Creating a built-in AJAX object
var ajax = new XMLHttpRequest();
// Tell the method, URL of request and make is asynchronous
ajax.open("POST", "http://localhost:3000/fetch-users", true);
// Detecting request state change
ajax.onreadystatechange = function () {
// Called when the response is successfully received
if (this.readyState == 4) {
if (this.status == 200) {
// For debugging purpose only
// console.log(this.responseText);
// Converting JSON string to Javasript array
var response = JSON.parse(this.responseText);
// Update state variable
setUsers(response.users);
// Set if there are more pages
setHasMorePages(response.hasMorePages);
// Set pagination
setPages(response.pages);
}
}
};
// Create form data object
const formData = new FormData();
// Attach current page number
formData.append("page", page);
// Send the request
ajax.send(formData);
}
// Run function when page value updates
React.useEffect(function () {
loadMore();
}, [refetch]);
return (
<>
{/* Display data */}
{ users.map(function (user) {
return (
<p key={ `user-${ user._id }` }>{ user.name }</p>
);
}) }
{/* Show pagination if required */}
{ pages > 1 && (
<nav>
<ul>
{ Array.from({ length: pages }, function (_, index) { return index + 1 } ).map(function (p) {
return (
<li key={ `pagination-${ p }` } className={ `page-item ${ p == page ? "active" : "" }` }>
<a href="#" onClick={ function (event) {
event.preventDefault();
setPage(p);
setRefetch(refetch + 1);
} }>{ p }</a>
</li>
);
}) }
</ul>
</nav>
) }
</>
);
}
ReactDOM.createRoot(
document.getElementById("app")
).render(<App />);
</script>
Node.js and MongoDB
Now in our Node.js server, we will create an API that will return all the records based on the current page from client side. It will also return the number of pagination links.
const express = require("express");
const app = express();
const http = require("http").createServer(app);
const mongodb = require("mongodb");
const ObjectId = mongodb.ObjectId;
const MongoClient = mongodb.MongoClient;
const cors = require("cors");
app.use(cors("http://localhost/pagination-in-react-node-js-and-mongodb"));
const expressFormidable = require("express-formidable");
app.use(expressFormidable({
multiples: true
}));
const port = process.env.PORT || 3000;
const databaseName = "test"
const MONGO_URI = process.env.MONGO_URI || "mongodb://127.0.0.1:27017";
http.listen(port, async function () {
console.log("Server started");
const client = new MongoClient(MONGO_URI);
try {
await client.connect();
const db = client.db(databaseName);
console.log("Database connected.");
app.post("/fetch-users", async function (request, result) {
const limit = 2;
const page = parseInt(request.fields.page || 1);
const skip = (page - 1) * limit;
const users = await db.collection("users")
.find({})
.sort({
_id: 1
})
.skip(skip)
.limit(limit)
.toArray();
const usersArr = [];
for (let a = 0; a < users.length; a++) {
const obj = {
_id: users[a]._id || "",
name: users[a].name || ""
};
usersArr.push(obj);
}
const totalCount = await db.collection("users").countDocuments({});
const hasMorePages = (page * limit) < totalCount;
const pages = Math.ceil(totalCount / limit);
result.json({
status: "success",
message: "Data has been fetched.",
users: users,
hasMorePages: hasMorePages,
pages: pages
});
});
} catch (exp) {
console.log(exp.message);
}
});
That’s how you can create pagination links in your React app with Node.js and MongoDB as backend. If you face any problem in following this, feel free to contact me.