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

React Paginated table

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

View Comments

  • 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.

Recent Posts

Why parseInt(’09’) Returns 0

If you've ever encountered the puzzling behavior of parseInt('09') returning 0 in JavaScript, you're not…

2 days ago

Event Bubbling and Capturing: Why Your Click Listener Fires Twice (And How to Fix It)

If you’ve ever built an interactive web application, you may have encountered a puzzling issue:…

1 week ago

Practical Array Methods for Everyday Coding

Arrays are the backbone of programming, used in nearly every application. Whether you're manipulating data,…

2 weeks ago

What the Heck Is the Event Loop? (Explained With Pizza Shop Analogies)

If you've ever tried to learn JavaScript, you’ve probably heard about the "Event Loop"—that mysterious,…

2 weeks ago

Why [] === [] Returns false in JavaScript (And How to Properly Compare Arrays & Objects)

JavaScript can sometimes behave in unexpected ways, especially when comparing arrays and objects. If you've…

2 weeks ago

Recursion for Beginners

Recursion is a programming technique where a function calls itself to solve smaller instances of…

2 weeks ago