Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Paginate Second Instance on same page does not re render

I am using react-paginate for pagination and I have two instances on the same page. One on top and one on the bottom, when new prop is received only top one is re-rendered. Below is the code, I have checked the different lifecycle methods on the component if it receives new props and render method is called, all seems to be working but in the page only top pagination works meaning if I click on Page 2, second instance should also change to Page 2 because it received a new value for selected page. Any thoughts?

 import React from 'react';
 import ReactPaginate from 'react-paginate';

    export default class Pager extends React.Component {
      constructor() {
        super();
      }

      render() {

        return (
          <div className={`pager ${this.props.position}`}>
            <ReactPaginate 
              previousLabel={'Prev'}
              nextLabel = {'Next'}
              breakLabel = {<a href="">...</a>}
              breakClassName = {"break-me"}
              pageCount = {this.props.totalPages}
              marginPagesDisplayed ={1}
              pageRangeDisplayed={2}
              onPageChange = {this.props.onPageNumberClick}
              containerClassName = {"page-links-container"}
              pageLinkClassName = {"pg-links"}
              activeClassName = {"active"} 
              previousClassName = {"prev-pg-lnk"}
              nextClassName = {"next-pg-lnk"}
              disabledClassName = {"disabled"}
              initialPage = {parseInt(this.props.selectedPage) -1}
              />
          </div>
        );
      }
    }
like image 386
sayayin Avatar asked Dec 09 '16 21:12

sayayin


1 Answers

You have to use forcePage prop to sync the both paginations.

So once a page is changed, in onPageChange callback you update the state of a wrapper component (that holds both pagination components) with the updated page number. To make both paginations work in sync - you have to set forcePage to be equal to the wrapper's state selected page numer.

I've tested it locally with the plugin's official demo. Here is the example code (focus on render and handlePageClick methods):

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import ReactPaginate from 'react-paginate';
import $ from 'jquery';

window.React = React;


export class CommentList extends Component {
  render() {
    let commentNodes = this.props.data.map(function(comment, index) {
      return (
        <div key={index}>{comment.comment}</div>
      );
    });

    return (
      <div id="project-comments" className="commentList">
        <ul>
          {commentNodes}
        </ul>
      </div>
    );
  }
};

export class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      data: [],
      offset: 0,
      selected: null
    }
  }

  loadCommentsFromServer() {
    $.ajax({
      url      : this.props.url,
      data     : {limit: this.props.perPage, offset: this.state.offset},
      dataType : 'json',
      type     : 'GET',

      success: data => {
        this.setState({data: data.comments, pageCount: Math.ceil(data.meta.total_count / data.meta.limit)});
      },

      error: (xhr, status, err) => {
        console.error(this.props.url, status, err.toString());
      }
    });
  }

  componentDidMount() {
    this.loadCommentsFromServer();
  }

  handlePageClick = (data) => {
    let selected = data.selected;
    let offset = Math.ceil(selected * this.props.perPage);

    this.setState({offset: offset, selected}, () => {
      this.loadCommentsFromServer();
    });
  };

  render() {
    return (
      <div className="commentBox">
        <CommentList data={this.state.data} />
        <ReactPaginate previousLabel={"previous"}
                       nextLabel={"next"}
                       breakLabel={<a href="">...</a>}
                       breakClassName={"break-me"}
                       pageCount={this.state.pageCount}
                       marginPagesDisplayed={2}
                       pageRangeDisplayed={5}
                       onPageChange={this.handlePageClick}
                       containerClassName={"pagination"}
                       subContainerClassName={"pages pagination"}
                       activeClassName={"active"}
                       forcePage={this.state.selected} />

        <ReactPaginate previousLabel={"previous"}
                       nextLabel={"next"}
                       breakLabel={<a href="">...</a>}
                       breakClassName={"break-me"}
                       pageCount={this.state.pageCount}
                       marginPagesDisplayed={2}
                       pageRangeDisplayed={5}
                       onPageChange={this.handlePageClick}
                       containerClassName={"pagination"}
                       subContainerClassName={"pages pagination"}
                       activeClassName={"active"}
                       forcePage={this.state.selected} />
      </div>
    );
  }
};

ReactDOM.render(
  <App url={'http://localhost:3000/comments'}
       author={'adele'}
       perPage={10} />,
  document.getElementById('react-paginate')
);
like image 106
Jordan Enev Avatar answered Nov 12 '22 04:11

Jordan Enev