react paginated table

A React paginated table is useful when presenting data in an organised and readable format. It’s a way to present information in a manageable and organized manner, especially when dealing with a large amount of data that wouldn’t fit comfortably on a single page.

This tutorial shows you how to create your own paginated table fast and easy in React JS without using DataTables or any other framework for that matter.

Want to use React with DataTables? See this tutorial instead

Benefits of Paginated Tables

Key features of a paginated table include:

  1. Pagination Controls: Paginated tables typically include controls such as page navigation buttons (e.g., “Next Page,” “Previous Page”), page number indicators, and sometimes a dropdown menu to select the number of items displayed per page.
  2. Data Organization: The data is organized into rows and columns, similar to a traditional table. Each row represents a single record or entry, while each column represents a specific attribute or field of the data.
  3. Limited Display: Only a subset of the total dataset is displayed on each page, usually determined by the number of rows visible per page. This helps to prevent information overload and improves the user experience by presenting a manageable amount of data at a time.
  4. Navigation: Users can navigate between pages to view different segments of the dataset. Pagination controls allow users to move forward or backward through the pages, jump to a specific page, or adjust the number of items displayed per page.
  5. Efficient Loading: Paginated tables often incorporate techniques to efficiently load data, such as lazy loading, where additional pages of data are fetched from the server as needed, or server-side pagination, where only the relevant subset of data is retrieved from the server for each page.

Let’s see how to create a paginated table from an API data.

1. Get Data From The API

constructor(props){
     super(props);
     this.state = {
       data: [],
       postsPerPage: 10,
       currentPage: 1
     }
   } 

getPosts = async () => {
     const url = "https://jsonplaceholder.typicode.com/todos/";
     const obj = {
       method: "GET",
       headers: {
         Accept: "application/json",
         "Content-Type": "application/json"
       }
     }

     await fetch(`${url}`, obj)
     .then((response) => response.json())
     .then((responseJson) => {
       console.warn(responseJson);
       this.setState({ data: responseJson })
     })
     .catch((error) => {
       console.warn(error);
     })
   }

2. Display data from the API on the table

showData = () => {

      const { postsPerPage, currentPage, data } = this.state;
      const indexOfLastPage = currentPage * postsPerPage;
      const indexOfFirstPage = indexOfLastPage - postsPerPage;
      const currentPosts = data.slice(indexOfFirstPage, indexOfLastPage)

     try{
     return currentPosts.map((item, index) => {
       return(
         <tbody>
         <tr>
         <td>{postsPerPage * (currentPage-1)+index+1}</td>
         <td>{item.userId}</td>
         <td>{item.title}</td>
         <td>{item.completed.toString()}</td>
         </tr>
         </tbody>
       )
     })
   }catch(e){
     alert(e.message)
   }
   }

 render() {
     return (
       <div className="container">
       <table className="table align-items-center justify-content-center mb-0">
       <thead>
       <tr>
       <th>S/N</th>
       <th>UserId</th>
       <th>Title</th>
       <th>Completed</th>
       </tr>
       </thead>
       {this.showData()}
       </table>
      </div>
      )
}

3. Add the pagination component

 showPagination = () => {
     const { postsPerPage, data } = this.state;
     const pageNumbers = [];
     const totalPosts = data.length;

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

     const pagination = (pageNumbers) => {
       this.setState({currentPage: pageNumbers})
     }

     return(
       <nav>
       <ul className="pagination">
       {pageNumbers.map(number => (
         <li key={number} className={this.state.currentPage === number ? 'page-item active' : 'page-item' }>
         <button onClick={()=> pagination(number)} className="page-link"> {number} </button>
         </li>
       ))}
       </ul>
       </nav>
     )
   }

Here’s the full code for the React paginated table:

import React, { Component } from 'react';
import './App.css';

 class App extends Component {

   constructor(props){
     super(props);
     this.state = {
       data: [],
       postsPerPage: 10,
       currentPage: 1
     }
   }

   getPosts = async () => {
     const url = "https://jsonplaceholder.typicode.com/todos/";
     const obj = {
       method: "GET",
       headers: {
         Accept: "application/json",
         "Content-Type": "application/json"
       }
     }

     await fetch(`${url}`, obj)
     .then((response) => response.json())
     .then((responseJson) => {
       console.warn(responseJson);
       this.setState({ data: responseJson })
     })
     .catch((error) => {
       console.warn(error);
     })
   }



   showData = () => {

      const { postsPerPage, currentPage, data } = this.state;
      const indexOfLastPage = currentPage * postsPerPage;
      const indexOfFirstPage = indexOfLastPage - postsPerPage;
      const currentPosts = data.slice(indexOfFirstPage, indexOfLastPage)

     try{
     return currentPosts.map((item, index) => {
       return(
         <tbody>
         <tr>
         <td>{postsPerPage * (currentPage-1)+index+1}</td>
         <td>{item.userId}</td>
         <td>{item.title}</td>
         <td>{item.completed.toString()}</td>
         </tr>
         </tbody>
       )
     })
   }catch(e){
     alert(e.message)
   }
   }

   showPagination = () => {
     const { postsPerPage, data } = this.state;
     const pageNumbers = [];
     const totalPosts = data.length;

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

     const pagination = (pageNumbers) => {
       this.setState({currentPage: pageNumbers})
     }

     return(
       <nav>
       <ul className="pagination">
       {pageNumbers.map(number => (
         <li key={number} className={this.state.currentPage === number ? 'page-item active' : 'page-item' }>
         <button onClick={()=> pagination(number)} className="page-link"> {number} </button>
         </li>
       ))}
       </ul>
       </nav>
     )


   }

   componentDidMount(){
     this.getPosts()
   }

   render() {
     return (
       <div className="container">
       <table className="table align-items-center justify-content-center mb-0">
       <thead>
       <tr>
       <th>S/N</th>
       <th>UserId</th>
       <th>Title</th>
       <th>Completed</th>
       </tr>
       </thead>
       {this.showData()}
       </table>

       <div style={{ float: 'right' }}>
       {this.showPagination()}
       </div>

       </div>
     );
   }
 }

export default App;

Result of the React paginated table

Have anything to add? Let me know in the comments.

One thought on “React Paginated Table”
  1. Nice tutorial,can you please explain how I can add a search bar to this kind of pagination table that only searches data through ID alone.

Leave a Reply

Your email address will not be published. Required fields are marked *