stone rock
stone rock

Reputation: 1953

How to implement pagination on frontend in ReactJS?

I have made cricket web app using ReactJS, NodeJS, MongoDB. On frontend I am displaying data from JSON objects per page I want to display 16 JSON objects. I am using .slice(0,16) method to slice JSON objects from REST API which returns 577 objects. Now how can I implement pagination for page 2,3,4,5.

For page 2 -> slice(17,33) For page 3 -> slice(34,49) and so on...

Below is my code and screenshot of my webapp:

in content.js :

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

class Content extends Component {
    constructor(props){
        super(props);
        this.state = {
            matches:[],
            loading:true
        };
    }

    componentDidMount(){
        fetch('api/matches')
        .then(res => res.json())
        .then(res => {
      console.log(res)
      this.setState({
        matches:res.slice(0,16),
        loading:false
      })
    })
    }

    renderMatches() {
        return this.state.matches.map(match => {
            return (
                <div class="col-lg-3">
                    <div id="content">
                        <p class="match">MATCH {match.id}</p>
                        <h4>{match.team1}</h4>
                        <p>VS</p>
                        <h4>{match.team2}</h4>
                        <div class="winner">
                            <h3>WINNER</h3>
                            <h4>{match.winner}</h4>
                        </div>
                        <div class="stats">
                            <button type="button" class="btn btn-success">View Stats</button>
                        </div>
                    </div>
                </div>
            );
        })
    }

    render() {

        if (this.state.loading) {
            return <div>>Loading...</div>
        }

    return (
      <div>
          <div class="row">
            {this.renderMatches()}
          </div>
      </div>
    );
  }
}

export default Content;

In Pagination.js :

import React, { Component } from 'react';

class Pagination extends Component {

  render() {
    return (
      <div>
          <div class="container">
              <h2>Pagination</h2>
              <p>The .pagination class provides pagination links:</p>                  
              <ul class="pagination">
                <li><a href="#">1</a></li>
                <li><a href="#">2</a></li>
                <li><a href="#">3</a></li>
                <li><a href="#">4</a></li>
                <li><a href="#">5</a></li>
              </ul>
          </div>
      </div>
    );
  }
}

export default Pagination;

Screenshot for more clarity : enter image description here

enter image description here

enter image description here

Upvotes: 2

Views: 3843

Answers (1)

nbkhope
nbkhope

Reputation: 7474

How about store all the matches in the component state and only slice during rendering, based on the page query string?

In componentDidMount(), after fetching the data, simply set the state with all the matches:

  this.setState({
    matches: res,
  })

Then, given you want to control the pagination with a query string in the url, like:

?page=2

You can filter the matches in render():

const RECORDS_PER_PAGE = 16;
const page = parseInt(getPageNumber(), 10) || 1; // defaults to 1 if no page query specified
const offset = (page - 1) * RECORDS_PER_PAGE

// do your mapping (do this in your renderMapping() method)
const matchComponents = this.state.matches.slice(0 + offset, RECORDS_PER_PAGE + offset).map(/* ... */);

where getPageNumber() is a method that gives you the query string value for page:

// Use your own query string parser if you wish
getPageNumber() {
  return window.location.search // <-- gives you access to the query parameters
  .slice(1) // remove the `?`
  .split("&")
  .reduce((queryHash, queryParam) => {

    // e.g. ?page=3 becomes ["page", "3"]
    const query = queryParam.split('=');
    return Object.assign({}, queryHash, ({
      [query[0]]: query[1] || null
    }));

  }, {}).page;
}

Upvotes: 4

Related Questions