How to do Pagination In ReactJS

What is Pagination?

Pagination is the method used to display data on different pages. Like if in react app we are fetching data and that data is presented on the web page but the data e too long for the page then we use the concept of pagination where a certain number of data is displayed on one page and other data are placed on further similar pages.

As we know React is a single page web app, here we do not create multiple pages for pagination. We use different functions to render a specific amount of data on one page (1-10) and the remaining data on other pages with the same proportion. Pagination is used on a tremendous amount of websites.

In this tutorial, we will learn to paginate in react using from sctarch.

Pagination in React

In React we can use pagination easily by calculating a number of data and dividing them in the same proportion on different pages. As react is based on components and we know components can be reused many times so here also we will create a component to display data and components for pagination buttons.

Here we are gonna fetch some dummy data from a website called JSON placeholder
Link:  https://jsonplaceholder.typicode.com/

This website provides JSON data of different types for this example we will fetch todos.

How to do Pagination In React

Step 1:- Create react app and run it

npx create-react-app appname
cd> appname
npm start

Step 2:- Create a component folder inside the src folder to store components files like Todo.js and Pagination.js

 

Step 3:- Create a file Todo.js to write the component of todos

import React from 'react';

const Todos = ({ todos, loading }) => {
  if (loading) {
    return <h2>Loading...</h2>;
  }

  return (
    <ul className='list-group mb-4'>
      {todos.map(todo => (
        <li key={todo.id} className='list-group-item'>
          {todo.title}
        </li>
      ))}
    </ul>
  );
};

export default Todos;

Here we created a classed based component named Todo and export it. It has two props todos and loading, which will be passed from app.js file, where todos is the list of todos fetched from the site and loading is the state which will show that if todos are fetched.

Step 4:- Create a file called Pagintion.js in Components Folder

import React from 'react';

const Pagination = ({ todosPerPage, totalTodos, paginate }) => {
  const pageNumbers = [];

  for (let i = 1; i <= Math.ceil(totalTodos / todosPerPage); i++) {
    pageNumbers.push(i);
  }

  return (
    <nav>
      <ul className='pagination'>
        {pageNumbers.map(number => (
          <li key={number} className='page-item'>
            <a onClick={() => paginate(number)} href='!#' className='page-link'>
              {number}
            </a>
          </li>
        ))}
      </ul>
    </nav>
  );
};

export default Pagination;

Here we created a class-based component and exported it where we pass 3 props that are todosPerPage, totoalTodos and pagination. paginate is the function that is provided with the number as input and that will render that pages data.

Step 5:- Configuring App.js file

Here we import all components in the app.js file and with the help of useState and useEffect Hooks we fetch data from the above URL and store the in states.

For current todos on that page, we use page number and number of todo to calculate the last index and by subtracting it with todosPerPage we get the index of the first todo on any particular page and then we use slice function with first and last index as parameters and get all current todos.

We then pass this todo in the TODO component as a prop and fetch the list of todos on that page

And For pagination, we pass the length of todos and numbers along with per page so that we can keep track of the list

import React, { useState, useEffect } from 'react';
import Todos from './components/Todos';
import Pagination from './components/Pagination';
import axios from 'axios';
import './App.css';

const App = () => {
  const [todos, setTodos] = useState([]);
  const [loading, setLoading] = useState(false);
  const [currentPage, setCurrentPage] = useState(1);
  const [todosPerPage] = useState(10);

  useEffect(() => {
    const fetchPosts = async () => {
      setLoading(true);
      const res = await axios.get('https://jsonplaceholder.typicode.com/todos');
      setTodos(res.data);
      setLoading(false);
    };

    fetchPosts();
  }, []);

  // Get current Todo
  const indexOfLastTodo = currentPage * todosPerPage;
  const indexOfFirstTodo = indexOfLastTodo - todosPerPage;
  const currentTodos = todos.slice(indexOfFirstTodo, indexOfLastTodo);

  // Change page
  const paginate = pageNumber => setCurrentPage(pageNumber);

  return (
    <div className='container mt-5'>
      <h1 className='text-success mb-3'>Todo List</h1>
      <Todos todos={currentTodos} loading={loading} />
      <Pagination
        todosPerPage={todosPerPage}
        totalTodos={todos.length}
        paginate={paginate}
      />
    </div>
  );
};

export default App;

 

OutPut:-