Implement Pagination in React App
Pagination is an essential aspect of user interface design, particularly in web applications dealing with extensive datasets. It allows users to navigate through content conveniently, enhancing their experience by breaking down information into manageable chunks. In this tutorial, we’ll dive into the implementation of pagination within a React application using the react-paginate
library. By following these steps and utilizing a practical example, you'll gain a solid understanding of how to integrate pagination seamlessly into your React projects.

Prerequisites: Before diving into the implementation, ensure you have the following prerequisites:
- Basic understanding of React: Familiarity with React concepts such as components, state management, and lifecycle methods is essential.
- Node.js and npm (or yarn) installed.
Step-1:
- Create a react app using VITE
npm create vite@latest pagination-project -- --template react
cd pagination-project
Step -2 :
- Install required libraries
npm i react-paginate
Step-3:
- Open your component where you want to implement pagination, In my case i want to implement pagination on my App.jsx . Then import pagination from react-paginate library.
import ReactPaginate from 'react-paginate';
Step-4:
- Now declare a state to manage the current page
const [currentPage, setCurrentPage] = useState(0);
- The
useState
hook is used to initialize state within a functional component. - In this line,
currentPage
is the state variable representing the currently selected page number, andsetCurrentPage
is the function used to update its value. - By default, the initial value of
currentPage
is set to0
usinguseState(0)
.
2. Sample data and pagination logic
const itemsPerPage = 3;
const data = [ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" ]; // Sample data array
const offset = currentPage * itemsPerPage;
const paginatedItems = data.slice(offset, offset + itemsPerPage);
- Items Per Page (
itemsPerPage
):
const itemsPerPage = 3;
itemsPerPage
represents the number of items you want to display on each page of your paginated list.- In your example, you’ve set
itemsPerPage
to3
, meaning that each page will display three items.
2. Sample Data Array (data
):
const data = [ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" ];
data
is an array containing the entire dataset that you want to paginate.- Each element in the array represents an item in your dataset. In your example, it contains letters from “A” to “Z”.
3. Offset Calculation:
const offset = currentPage * itemsPerPage;
- The
offset
calculates the starting index of the current page within thedata
array. - It’s determined by multiplying the current page number (
currentPage
) by the number of items per page (itemsPerPage
). - For example, if
currentPage
is0
anditemsPerPage
is3
, theoffset
would be0 * 3 = 0
, meaning that the first page starts from index0
in thedata
array.
4. Paginated Items (paginatedItems
):
const paginatedItems = data.slice(offset, offset + itemsPerPage);
paginatedItems
represents the subset of data that should be displayed on the current page.- It uses the
slice
method to extract a portion of thedata
array, starting from the calculatedoffset
and ending atoffset + itemsPerPage
. - For example, if
offset
is0
, andoffset + itemsPerPage
is0 + 3 = 3
,paginatedItems
would contain the first three items of thedata
array (indexes0
,1
, and2
).
Let’s illustrate with an example:
- Suppose you have
data = ["A", "B", "C", "D", "E", "F", "G", "H", "I"]
. - If
currentPage
is1
anditemsPerPage
is3
, then: offset
would be1 * 3 = 3
, indicating that the current page starts from index3
.paginatedItems
would contain items from index3
to index5
in thedata
array (["D", "E", "F"]
), representing the items displayed on the second page.
3. Rendering Paginated Items
{ paginatedItems.map(item => (
<h1>Item #{item}</h1>
)) }
- This JSX code maps over the
paginatedItems
array and renders each item as an<h1>
element. - In your example, each item in
paginatedItems
is a string representing a letter from the alphabet (e.g., "A", "B", "C").
4. Now we need a pagination function to handle the pagination
const handlePageChange = ({ selected }) => {
setCurrentPage(selected);
};
handlePageChange
is a function that updates thecurrentPage
state variable when a new page is selected in the pagination component.- It receives an object containing the
selected
page number as an argument from theReactPaginate
component.
5. Pagination Component
<ReactPaginate
previousLabel={"Previous"}
nextLabel={"Next"}
breakLabel={"..."}
breakClassName={"break-me"}
pageCount={Math.ceil(data.length / itemsPerPage)}
marginPagesDisplayed={5}
pageRangeDisplayed={2}
onPageChange={handlePageChange}
containerClassName={
"flex justify-center gap-3 items-center font-poppins text-xs"
}
activeClassName={
"bg-transparent border-b-4 border-gray-800 text-white rounded-lg font-medium py-2"
}
pageLinkClassName={
"bg-transparent text-gray-800 border border-gray-800 rounded-lg font-medium px-3 py-2"
}
previousLinkClassName={
"bg-gray-800 text-white lg:px-4 px-3 text-xs lg:text-base py-2 rounded-lg font-medium"
}
nextLinkClassName={
"bg-gray-800 text-white lg:px-4 px-3 text-xs lg:text-base py-2 rounded-lg font-medium"
}
disabledClassName={"pointer-events-none opacity-50"}
/>
5.1 — previousLabel
and nextLabel
:
- These props define the labels for the “Previous” and “Next” buttons in the pagination component.
- For example,
previousLabel={"Previous"}
sets the label for the "Previous" button to "Previous".
5.2 — breakLabel
and breakClassName
:
breakLabel
specifies the label to be displayed for ellipsis ("...") when there are multiple pages.breakClassName
sets the CSS class name for the ellipsis element.
5.3 — pageCount
:
pageCount
specifies the total number of pages in the pagination component.- It’s calculated by dividing the total number of items in the dataset (
data.length
) by the number of items per page (itemsPerPage
) and rounding up usingMath.ceil
.
5.4 -marginPagesDisplayed
and pageRangeDisplayed
:
- These props control how many page links are displayed around the current page.
marginPagesDisplayed
determines the number of pages to display at the beginning and end of the pagination component.pageRangeDisplayed
specifies the number of pages to display before and after the current page.
5.5 -onPageChange
:
onPageChange
is a function prop that gets called when a new page is selected.- We pass the
handlePageChange
function to theonPageChange
prop. This means that when a user interacts with the pagination controls, thehandlePageChange
function will be called, updating thecurrentPage
state variable accordingly.
5.6 -containerClassName
:
containerClassName
sets the CSS class name for the container element that wraps the pagination component.- In this example, it’s used to apply styling to the container using Tailwind CSS classes.
5.7 -activeClassName
, pageLinkClassName
, previousLinkClassName
, and nextLinkClassName
:
- These props define the CSS class names for various elements within the pagination component.
activeClassName
sets the class name for the currently active page link.pageLinkClassName
sets the class name for the page links.previousLinkClassName
andnextLinkClassName
set the class names for the "Previous" and "Next" buttons, respectively.
5.8 -disabledClassName
:
disabledClassName
specifies the class name for disabled elements, such as disabled "Previous" or "Next" buttons.
In this example, i used to apply styling to disabled elements using Tailwind CSS classes.
After successfully implementing our pagination, it will look like this:

Finally, Our App.jsx:
import React, { useState } from "react";
import ReactPaginate from "react-paginate";
const App = () => {
const [currentPage, setCurrentPage] = useState(0);
const itemsPerPage = 3;
const data = [ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" ];
const handlePageChange = ({ selected }) => {
setCurrentPage(selected);
};
const offset = currentPage * itemsPerPage;
const paginatedItems = data.slice(offset, offset + itemsPerPage);
return (
<>
<div className="flex flex-col items-center justify-center w-full h-[300px]">
{paginatedItems.map((item) => (
<h1>Item #{item}</h1>
))}
</div>
<ReactPaginate
previousLabel={"Previous"}
nextLabel={"Next"}
breakLabel={"..."}
breakClassName={"break-me"}
pageCount={Math.ceil(data.length / itemsPerPage)}
marginPagesDisplayed={5}
pageRangeDisplayed={2}
onPageChange={handlePageChange}
containerClassName={
"flex justify-center gap-3 items-center font-poppins text-xs"
}
activeClassName={
"bg-transparent border-b-4 border-gray-800 text-white rounded-lg font-medium py-2"
}
pageLinkClassName={
"bg-transparent text-gray-800 border border-gray-800 rounded-lg font-medium px-3 py-2"
}
previousLinkClassName={
"bg-gray-800 text-white lg:px-4 px-3 text-xs lg:text-base py-2 rounded-lg font-medium"
}
nextLinkClassName={
"bg-gray-800 text-white lg:px-4 px-3 text-xs lg:text-base py-2 rounded-lg font-medium"
}
disabledClassName={"pointer-events-none opacity-50"}
/>
</>
);
};
export default App;
Conclusion:
In short, implementing pagination in a React application using react-paginate
provides users with a streamlined way to navigate through large datasets. By breaking data into manageable chunks and offering intuitive navigation controls, pagination enhances performance and user experience. Through this tutorial, we've covered setting up pagination, handling state, rendering paginated data, and customizing pagination controls. With pagination in place, your React app becomes more efficient and user-friendly, ensuring users can easily explore and interact with your data.