ReactJS: Supporting Server Side Pagination for React-Table

on Reading Time: 2 minutes

Supporting Server Side Pagination

Although at first server side pagination might seem to be difficult, with react-table, it’s as simple as configuring the API properly.  After reading this post, you will be able to learn the SQL queries required to provide the pagination functionality.

The following table will be used for demonstration purposes.

import React from "react";
import ReactTable from "react-table";
import "react-table/react-table.css";

class Table extends React.Component {
   constructor() {
       super();
       this.state = {
          data: this.props.data,
          loading: false,
          pages: 0
       };
   }

    render() {
          const { data } = this.state;
          return (
                  <ReactTable
                       data={data}
                       columns={[
                             {
                               Header: "Index",
                               accessor: "index"
                             },
                             {
                               Header: "Status",
                               accessor: "status"
                             },
                             {
                               Header: "Name",
                               accessor: "name"
                              }
                            ]}
                     defaultPageSize={10}
                     className="-striped -highlight"
                    />
         );
     }
}

The first step would be to enable server-side pagination and inserting the function to retrieve data from the server. You will need to add the below code snippet in the react-table configuration section.  Please note that I have defined a separate service to obtain the data from the server. I will explain this method later in the post.

loading={this.state.loading}
showPagination={true}
showPaginationTop={false}
showPaginationBottom={true}
pageSizeOptions={[5, 10, 20, 25, 50, 100]}
manual  // this would indicate that server side pagination has been enabled 
onFetchData={(state, instance) => {
    this.setState({loading: true});
    testService.getTestData(state.page, state.pageSize, state.sorted, state.filtered, (res) => {
        this.setState({
            data: res.data.rows,
            pages: res.data.pages,
            loading: false
        })
    });
}}

After the modification, the component would look as below.

import React from "react";
import ReactTable from "react-table";
import "react-table/react-table.css";

class Table extends React.Component {
   constructor() {
       super();
       this.state = {
          data: this.props.data,
          loading: false,
          pages: 0
       };
   }

    render() {
          const { data } = this.state;
          return (
                  <ReactTable
                       data={data}
                       pages={this.state.pages}
                       columns={[
                             {
                               Header: "Index",
                               accessor: "index"
                             },
                             {
                               Header: "Status",
                               accessor: "status"
                             },
                             {
                               Header: "Name",
                               accessor: "name"
                              }
                            ]}
                     defaultPageSize={10}
                     className="-striped -highlight"
                     loading={this.state.loading}
                     showPagination={true}
                     showPaginationTop={false}
                     showPaginationBottom={true}
                     pageSizeOptions={[5, 10, 20, 25, 50, 100]}
                     manual // this would indicate that server side pagination has been enabled 
                     onFetchData={(state, instance) => {
                             this.setState({loading: true});
                             testService.getTestData(state.page, state.pageSize, state.sorted, state.filtered, (res) => {
                             this.setState({
                                     data: res.data.rows,
                                     pages: res.data.pages,
                                     loading: false
                             })
                     });
                     }}
                     />
         );
     }
}

Next, let’s look at the test service. Please note that you will have to customize your callback function based on your requirement.

getTestData(page, pageSize, sorted, filtered, handleRetrievedData) {
    let url = this.baseURL + "/getData";
    let postObject = {
        page: page,
        pageSize: pageSize,
        sorted: sorted,
        filtered: filtered,
    }; 

    return this.post(url, postObject).then(response => handleRetrievedData(response)).catch(response => console.log(response));
}

post(url, params = {}) {
    return axios.post(url, params)
}

From your back-end, you will have to develop a method to obtain the total page count. For example, in nodejs you could do this by Math.ceil(parseFloat(results[0].count) / parseFloat(pageSize))  Afterwards, you need to retrieve the data using the page index and the page size.  For example you could use the following queries, 

countSql = 'SELECT count(*) AS count FROM entity';
dataSql = 'SELECT * FROM entity LIMIT ?,?';  //start index and page size respectively

To find the start index,  use  let startIndex = +pageNo * +pageSize;

Now you should be able to get the system running as soon as you configure your API. Cheers!

Don’t forget to leave a comment behind if this post was helpful. I really appreciate it! 🙏

2
Leave a Reply

avatar
1 Comment threads
1 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
malithGábor Hajdu Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
Gábor Hajdu
Guest
Gábor Hajdu

Great guide, thanks! I managed to set up pagination in 10 minutes. 🙂

One note:
Isn’t this line missing from the <ReactTable…?
pages={this.state.pages}
This will pass the count of all pages to the table to enable the pagination buttons.