Pagination | Rails — React — Redux

Dylan Williamson
3 min readApr 9, 2021

There is no denying that as programmers, space and time are a major concern when building scalable applications. Take a moment to think about a website such as Amazon. When you search for a product you might get back 10,000+ results, however only a select number of products are truly rendered. This isn’t because Amazon has some personal vendetta against allowing users to view all results on one page, it just wouldn’t be practical. This is where pagination comes into play.

Pagination Bar [Semantic UI]

What’s pagination?

Pagination is the process of limiting how much data is actually being sent. This also means knowing what information belongs to which page, and which page the user is currently on. This way, instead of loading all of our results, we might only load 30 products on one page, then the following 30 products would be loaded on the next page, and so on. I think you get the gist, let’s get to implementing!

— Backend

We will start by configuring our backend

Gemfile

We’re first going to add the will_paginate gem to our Gemfile

gem 'will_paginate'

The will_paginate gem will gives us a few methods which will do a majority of the backend work for us!

Model

In your model, you will want to define self.per_page

This is how many objects you would like to display per page, in my case 3

class Studio < ApplicationRecordhas_many :reviewshas_many :users, through: :reviewsself.per_page = 3end

Controller

We will need to update our index action to the following in order to correctly paginate our output as an API

class StudiosController < ApplicationControllerdef index@studios = Studio.paginate(:page => params[:page]render json: @studiosendend

In addition, we will also need to display what page is associated to the given data, as well as the total number of pages. This is where will_paginate comes in handy

class StudiosController < ApplicationControllerdef index@studios = Studio.paginate(:page => params[:page]render json: {
studios: @studios,
page: @studios.current_page,
pages: @studios.total_pages
}
endend

— Frontend

Let’s import the Semantic UI pagination bar to eliminate the need to construct one ourselves

Place your import at the top of whatever component you’re rendering it from

import { Pagination } from 'semantic-ui-react';

You’ll also need to place the Pagination element in your return

<PaginationonPageChange={ handlePage }size="mini"siblingRange="1"defaultActivePage={ page }totalPages={ pages }/>

onPageChange

Will contain a function to handle the changing of pages

siblingRange

How many pages left and right of current page

defaultActivePage

The current page

totalPages

Total amount of pages

Creating the handlePage function

Inside of our component, but outside of the return function, is where we will place our handlePage function

import { useDispatch } from 'react-redux';const handlePage = (e, { activePage }) => {let goToPage = { activePage };let pageNum = goToPage.activePage;let pageString = pageNum.toString();const url = "http://localhost:3000/studios/?page=" + pageString;fetch(url).then(res => res.json()).then(data => dispatch({type: "SET_STUDIOS",payload: data}));}

What this function does is fetches page results from our Rails API depending on the current page. It well then dispatch an action which I’ve labeled here as “SET_STUDIOS” which we will add in our action creators

export const setStudios = () => {return dispatch => {fetch(API + "/studios").then(res => res.json()).then(data => dispatch({type: "SET_STUDIOS",payload: data}))}}

This is a basic index action creator which you may already have configured into your application

Let’s also account for this in our reducer

const initialState = {studios: {studios: [],page: 1,page_count: 1}}const studiosReducer = (state=initialState, action) => {switch (action.type){case "SET_STUDIOS":return {...state, studios: action.payload}}}default:return {...state}}}

Congrats!

You should now have a fully functioning pagination bar!

--

--