Pagination With React Bootstrap

Cover Image

I’ve implemented pagination a few times now with React Bootstrap. Each time, it was more tedious and difficult than I imagined, especially compared to implementing other React Bootstrap components. The doc shows how to import the components for the buttons, but the functionality has to be coded by the developer. I was frustrated by this at first, but then realized that the design must have been non-opinionated so that the developer would have more control in how it was implemented. And fortunately, I was able to find some good resources explaining how to implement both the basic version and the more advanced version of pagination. I will explain both in this post.

To demonstrate pagination in React, we’re going to create a Pokemon app that consists of a table containing the first 151 Pokemon and their types. We will get the data from json-pokemon. We don’t want to see all 151 at once so we will paginate the table so that only a subset of the data is visible at one time.

If at anytime you want to see the final source code, you can find it here.

Initial Setup

First, open up a terminal and run:

Create React App

Next, open up the project in an IDE and remove these files:
Remove Unnecessary Files

Then, we’ll need to make some adjustments to index.js and App.js:

Finally, we need to replace what’s in index.css:

Install Dependencies

We also need to install Bootstrap. In the terminal, run:

Install Bootstrap

And we need to import that into index.js:

Next, we’re going to install json-pokemon to get data for the list we’re going to paginate:

Install json-pokemon

Create Components

To wrap up the project setup, inside the src folder, we’re going to create a components folder. And inside that folder we’re going to create two files, PokemonTable.jsx and Pagination.jsx:

Our Pagination component will reside in our PokemonTable component. But we need to bring our PokemonTable into App.js:

Run the App:

If you haven’t already, start the application with npm start:

Run the Application

Pokemon Table

Pagination

Basic Pagination

So, the code I have currently in Pagination.jsx is what Bootstrap gives you for basic pagination. We will have to add the functionality to make it work with our table.

We will need our Pagination component to know about our Pokemon data because it will need to determine what should be shown on a page based on what page number we’re on. There are a few ways we could do this, by passing an event handler from our PokemonTable component via props, or by using Redux Toolkit for state management. For the basic pagination example, I will use props, but when I implement advanced pagination later on, I will use Redux Toolkit.

Implementation

First, we will need to define some variables in PokemonTable, some of which we will pass to the Pagination component as props:

We defined an event handler, paginate, that will be passed to our Pagination component and be called any time a button is clicked. It will be used to show the appropriate pages depending on what active (current page) is. It will also allow us to manipulate our PokemonTable state from inside Pagination.

Next, we will need to make some changes to Pagination. We need to accept the props we passed from PokemonTable, and remove our local definition of active. Additionally, we need to iterate over the total number of pages in our for loop:

With that, our table should be paginating successfully:

Complete Pagination

This solution works, but I’m a much bigger fan of using Redux Toolkit here as opposed to passing all of the props. We have to keep track of our active page inside of PokemonTable, when it really makes sense for that to reside in the Pagination component. With Redux Toolkit, we wouldn’t need to pass any props to Pagination.

In the next section, I’ll show you how to implement advanced pagination using Redux Toolkit.

Advanced Pagination

I’m going to get Redux Toolkit set up quickly. If you want more explanation on how Redux Toolkit works, check out my blog post.

Adding Redux

First we need to install Redux Toolkit. In the terminal, run:

Install Redux Toolkit

Next, we need our slice files. In the src folder, we need to create a features folder. And inside the features folder, we need to create pagination and pokemons folders, and in those folders, we need to create paginationSlice.js and pokemonSlice.js files respectively:

We now need a Redux store. Again, in the src folder, we need to create an app folder. In that folder, we need to create a file, store.js:

And we need to bring that into index.js:

We need to make some adjustments in our Pagination and PokemonTable components so that they’re using Redux:

With those changes, our pagination should be working as before, except now the code is decoupled and is much cleaner. Our PokemonTable component doesn’t need to be concerned with details related to pagination. With Redux, that logic has all been moved to the Pagination component.

Implementing

The original code I found to create advanced pagination can be found here. I won’t go into the details of how it’s working because I think the best way to understand the code is to play around with it and spend time with it. However, I did make some enhancements to the original code, so I will go over those.

Let’s make a new component for this. In the components folder, create a new file, AdvancedPagination.jsx:

I improved on the original pagination in the repo by adding first page and last page buttons. Additionally, I opted out of using the ellipsis. Instead, I show all page increments of 10 regardless of what page you’re on. This is just personal preference. Some people may prefer the ellipsis.

And then let’s just replace the Pagination component we have in PokemonTable and replace that with the new AdvancedPagination component:

This works, we can now see the our advanced pagination in action:

Advanced Pagination

However, it would be better if we had a larger data set. Luckily, we can change that easily. In our pokemonSlice.js file, we need to change our state so that it uses the full JSON and not the first 151:

Now, we can see our advanced pagination in its full glory:

Advanced Pagination 2

Conclusion

I know I breezed through it, but like I said earlier, I think it boils down to the person reading to spend time with the code and mess around with it to see why it’s working the way it is. I spent several days trying to implement advanced pagination myself before stumbling upon the repo. I also had to spend some time with that code before I understood how to implement it and make the improvements that I did.

If you liked this post, make sure to subscribe so you don’t mess future posts!