How to implement pagination in reactions

I am new to ReactJS and am creating a simple TODO application in it. In fact, this is a very simple application without a db connection, tasks are stored in an array. I added the edit and delete function to it. Now I want to add pagination. How to implement it? Any help would be appreciated. Thanks...!!

+33
reactjs pagination
source share
11 answers

I recently implemented pagination in pure React JS. Here is a working demo: http://codepen.io/PiotrBerebecki/pen/pEYPbY

Of course, you will need to configure the logic and display the page numbers to fit your requirements.

Full code:

class TodoApp extends React.Component { constructor() { super(); this.state = { todos: ['a','b','c','d','e','f','g','h','i','j','k'], currentPage: 1, todosPerPage: 3 }; this.handleClick = this.handleClick.bind(this); } handleClick(event) { this.setState({ currentPage: Number(event.target.id) }); } render() { const { todos, currentPage, todosPerPage } = this.state; // Logic for displaying todos const indexOfLastTodo = currentPage * todosPerPage; const indexOfFirstTodo = indexOfLastTodo - todosPerPage; const currentTodos = todos.slice(indexOfFirstTodo, indexOfLastTodo); const renderTodos = currentTodos.map((todo, index) => { return <li key={index}>{todo}</li>; }); // Logic for displaying page numbers const pageNumbers = []; for (let i = 1; i <= Math.ceil(todos.length / todosPerPage); i++) { pageNumbers.push(i); } const renderPageNumbers = pageNumbers.map(number => { return ( <li key={number} id={number} onClick={this.handleClick} > {number} </li> ); }); return ( <div> <ul> {renderTodos} </ul> <ul id="page-numbers"> {renderPageNumbers} </ul> </div> ); } } ReactDOM.render( <TodoApp />, document.getElementById('app') ); 
+86
source share

I tried to recreate the simple paging example provided by piotr-berebecki , which was great. But when there will be many pages, then the pagination will be full on the screen. So, I used the previous and back buttons along with the forward and back buttons to stream between pages. And for design, I used bootstrap 3.

You can configure the number of pages to display by page, using page binding values. Make sure you use the same value for upperPageBound and pageBound.

  class TodoApp extends React.Component { constructor() { super(); this.state = { todos: ['a','b','c','d','e','f','g','h','i','j','k','l','m', 'n','o','p','q','r','s','t','u','v','w','x','y','z'], currentPage: 1, todosPerPage: 3, upperPageBound: 3, lowerPageBound: 0, isPrevBtnActive: 'disabled', isNextBtnActive: '', pageBound: 3 }; this.handleClick = this.handleClick.bind(this); this.btnDecrementClick = this.btnDecrementClick.bind(this); this.btnIncrementClick = this.btnIncrementClick.bind(this); this.btnNextClick = this.btnNextClick.bind(this); this.btnPrevClick = this.btnPrevClick.bind(this); // this.componentDidMount = this.componentDidMount.bind(this); this.setPrevAndNextBtnClass = this.setPrevAndNextBtnClass.bind(this); } componentDidUpdate() { $("ul li.active").removeClass('active'); $('ul li#'+this.state.currentPage).addClass('active'); } handleClick(event) { let listid = Number(event.target.id); this.setState({ currentPage: listid }); $("ul li.active").removeClass('active'); $('ul li#'+listid).addClass('active'); this.setPrevAndNextBtnClass(listid); } setPrevAndNextBtnClass(listid) { let totalPage = Math.ceil(this.state.todos.length / this.state.todosPerPage); this.setState({isNextBtnActive: 'disabled'}); this.setState({isPrevBtnActive: 'disabled'}); if(totalPage === listid && totalPage > 1){ this.setState({isPrevBtnActive: ''}); } else if(listid === 1 && totalPage > 1){ this.setState({isNextBtnActive: ''}); } else if(totalPage > 1){ this.setState({isNextBtnActive: ''}); this.setState({isPrevBtnActive: ''}); } } btnIncrementClick() { this.setState({upperPageBound: this.state.upperPageBound + this.state.pageBound}); this.setState({lowerPageBound: this.state.lowerPageBound + this.state.pageBound}); let listid = this.state.upperPageBound + 1; this.setState({ currentPage: listid}); this.setPrevAndNextBtnClass(listid); } btnDecrementClick() { this.setState({upperPageBound: this.state.upperPageBound - this.state.pageBound}); this.setState({lowerPageBound: this.state.lowerPageBound - this.state.pageBound}); let listid = this.state.upperPageBound - this.state.pageBound; this.setState({ currentPage: listid}); this.setPrevAndNextBtnClass(listid); } btnPrevClick() { if((this.state.currentPage -1)%this.state.pageBound === 0 ){ this.setState({upperPageBound: this.state.upperPageBound - this.state.pageBound}); this.setState({lowerPageBound: this.state.lowerPageBound - this.state.pageBound}); } let listid = this.state.currentPage - 1; this.setState({ currentPage : listid}); this.setPrevAndNextBtnClass(listid); } btnNextClick() { if((this.state.currentPage +1) > this.state.upperPageBound ){ this.setState({upperPageBound: this.state.upperPageBound + this.state.pageBound}); this.setState({lowerPageBound: this.state.lowerPageBound + this.state.pageBound}); } let listid = this.state.currentPage + 1; this.setState({ currentPage : listid}); this.setPrevAndNextBtnClass(listid); } render() { const { todos, currentPage, todosPerPage,upperPageBound,lowerPageBound,isPrevBtnActive,isNextBtnActive } = this.state; // Logic for displaying current todos const indexOfLastTodo = currentPage * todosPerPage; const indexOfFirstTodo = indexOfLastTodo - todosPerPage; const currentTodos = todos.slice(indexOfFirstTodo, indexOfLastTodo); const renderTodos = currentTodos.map((todo, index) => { return <li key={index}>{todo}</li>; }); // Logic for displaying page numbers const pageNumbers = []; for (let i = 1; i <= Math.ceil(todos.length / todosPerPage); i++) { pageNumbers.push(i); } const renderPageNumbers = pageNumbers.map(number => { if(number === 1 && currentPage === 1){ return( <li key={number} className='active' id={number}><a href='#' id={number} onClick={this.handleClick}>{number}</a></li> ) } else if((number < upperPageBound + 1) && number > lowerPageBound){ return( <li key={number} id={number}><a href='#' id={number} onClick={this.handleClick}>{number}</a></li> ) } }); let pageIncrementBtn = null; if(pageNumbers.length > upperPageBound){ pageIncrementBtn = <li className=''><a href='#' onClick={this.btnIncrementClick}> &hellip; </a></li> } let pageDecrementBtn = null; if(lowerPageBound >= 1){ pageDecrementBtn = <li className=''><a href='#' onClick={this.btnDecrementClick}> &hellip; </a></li> } let renderPrevBtn = null; if(isPrevBtnActive === 'disabled') { renderPrevBtn = <li className={isPrevBtnActive}><span id="btnPrev"> Prev </span></li> } else{ renderPrevBtn = <li className={isPrevBtnActive}><a href='#' id="btnPrev" onClick={this.btnPrevClick}> Prev </a></li> } let renderNextBtn = null; if(isNextBtnActive === 'disabled') { renderNextBtn = <li className={isNextBtnActive}><span id="btnNext"> Next </span></li> } else{ renderNextBtn = <li className={isNextBtnActive}><a href='#' id="btnNext" onClick={this.btnNextClick}> Next </a></li> } return ( <div> <ul> {renderTodos} </ul> <ul id="page-numbers" className="pagination"> {renderPrevBtn} {pageDecrementBtn} {renderPageNumbers} {pageIncrementBtn} {renderNextBtn} </ul> </div> ); } } ReactDOM.render( <TodoApp />, document.getElementById('app') ); 

Working demo link: https://codepen.io/mhmanandhar/pen/oEWBqx

Image: simple pagination reaction

+7
source share

I recently created this Pagination component that implements swap logic, such as Google search results:

 import React, { PropTypes } from 'react'; const propTypes = {    items: PropTypes.array.isRequired,    onChangePage: PropTypes.func.isRequired,    initialPage: PropTypes.number  } const defaultProps = {    initialPage: 1 } class Pagination extends React.Component {    constructor(props) {        super(props);        this.state = { pager: {} };    }    componentWillMount() {        this.setPage(this.props.initialPage);    }    setPage(page) {        var items = this.props.items;        var pager = this.state.pager;        if (page < 1 || page > pager.totalPages) {            return;        }        // get new pager object for specified page        pager = this.getPager(items.length, page);        // get new page of items from items array        var pageOfItems = items.slice(pager.startIndex, pager.endIndex + 1);        // update state        this.setState({ pager: pager });        // call change page function in parent component        this.props.onChangePage(pageOfItems);    }    getPager(totalItems, currentPage, pageSize) {        // default to first page        currentPage = currentPage || 1;        // default page size is 10        pageSize = pageSize || 10;        // calculate total pages        var totalPages = Math.ceil(totalItems / pageSize);        var startPage, endPage;        if (totalPages <= 10) {            // less than 10 total pages so show all            startPage = 1;            endPage = totalPages;        } else {            // more than 10 total pages so calculate start and end pages            if (currentPage <= 6) {                startPage = 1;                endPage = 10;            } else if (currentPage + 4 >= totalPages) {                startPage = totalPages - 9;                endPage = totalPages;            } else {                startPage = currentPage - 5;                endPage = currentPage + 4;            }        }        // calculate start and end item indexes        var startIndex = (currentPage - 1) * pageSize;        var endIndex = Math.min(startIndex + pageSize - 1, totalItems - 1);        // create an array of pages to ng-repeat in the pager control        var pages = _.range(startPage, endPage + 1);        // return object with all pager properties required by the view        return {            totalItems: totalItems,            currentPage: currentPage,            pageSize: pageSize,            totalPages: totalPages,            startPage: startPage,            endPage: endPage,            startIndex: startIndex,            endIndex: endIndex,            pages: pages        };    }    render() {        var pager = this.state.pager;        return (            <ul className="pagination">                <li className={pager.currentPage === 1 ? 'disabled' : ''}>                    <a onClick={() => this.setPage(1)}>First</a>                </li>                <li className={pager.currentPage === 1 ? 'disabled' : ''}>                    <a onClick={() => this.setPage(pager.currentPage - 1)}>Previous</a>                </li>                {pager.pages.map((page, index) =>                    <li key={index} className={pager.currentPage === page ? 'active' : ''}>                        <a onClick={() => this.setPage(page)}>{page}</a>                    </li>                )}                <li className={pager.currentPage === pager.totalPages ? 'disabled' : ''}>                    <a onClick={() => this.setPage(pager.currentPage + 1)}>Next</a>                </li>                <li className={pager.currentPage === pager.totalPages ? 'disabled' : ''}>                    <a onClick={() => this.setPage(pager.totalPages)}>Last</a>                </li>            </ul>        );    } } Pagination.propTypes = propTypes; Pagination.defaultProps export default Pagination; 

And here is an example application component that uses the Pagination component to break down a list of 150 examples:

 import React from 'react'; import Pagination from './Pagination'; class App extends React.Component {    constructor() {        super();        // an example array of items to be paged        var exampleItems = _.range(1, 151).map(i => { return { id: i, name: 'Item ' + i }; });        this.state = {            exampleItems: exampleItems,            pageOfItems: []        };        // bind function in constructor instead of render (https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md)        this.onChangePage = this.onChangePage.bind(this);    }    onChangePage(pageOfItems) {        // update state with new page of items        this.setState({ pageOfItems: pageOfItems });    }    render() {        return (            <div>                <div className="container">                    <div className="text-center">                        <h1>React - Pagination Example with logic like Google</h1>                        {this.state.pageOfItems.map(item =>                            <div key={item.id}>{item.name}</div>                        )}                        <Pagination items={this.state.exampleItems} onChangePage={this.onChangePage} />                    </div>                </div>                <hr />                <div className="credits text-center">                    <p>                        <a href="http://jasonwatmore.com" target="_top">JasonWatmore.com</a>                    </p>                </div>            </div>        );    } } export default App; 

For more information and a live demo, you can find this post.

+2
source share
  Sample pagination react js working code import React, { Component } from 'react'; import { Pagination, PaginationItem, PaginationLink } from "reactstrap"; let prev = 0; let next = 0; let last = 0; let first = 0; export default class SamplePagination extends Component { constructor() { super(); this.state = { todos: ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','T','v','u','w','x','y','z'], currentPage: 1, todosPerPage: 3, }; this.handleClick = this.handleClick.bind(this); this.handleLastClick = this.handleLastClick.bind(this); this.handleFirstClick = this.handleFirstClick.bind(this); } handleClick(event) { event.preventDefault(); this.setState({ currentPage: Number(event.target.id) }); } handleLastClick(event) { event.preventDefault(); this.setState({ currentPage:last }); } handleFirstClick(event) { event.preventDefault(); this.setState({ currentPage:1 }); } render() { let { todos, currentPage, todosPerPage } = this.state; // Logic for displaying current todos let indexOfLastTodo = currentPage * todosPerPage; let indexOfFirstTodo = indexOfLastTodo - todosPerPage; let currentTodos = todos.slice(indexOfFirstTodo, indexOfLastTodo); prev = currentPage > 0 ? (currentPage -1) :0; last = Math.ceil(todos.length/todosPerPage); next = (last === currentPage) ?currentPage: currentPage +1; // Logic for displaying page numbers let pageNumbers = []; for (let i = 1; i <=last; i++) { pageNumbers.push(i); } return ( <div> <ul> { currentTodos.map((todo,index) =>{ return <li key={index}>{todo}</li>; }) } </ul><ul id="page-numbers"> <nav> <Pagination> <PaginationItem> { prev === 0 ? <PaginationLink disabled>First</PaginationLink> : <PaginationLink onClick={this.handleFirstClick} id={prev} href={prev}>First</PaginationLink> } </PaginationItem> <PaginationItem> { prev === 0 ? <PaginationLink disabled>Prev</PaginationLink> : <PaginationLink onClick={this.handleClick} id={prev} href={prev}>Prev</PaginationLink> } </PaginationItem> { pageNumbers.map((number,i) => <Pagination key= {i}> <PaginationItem active = {pageNumbers[currentPage-1] === (number) ? true : false} > <PaginationLink onClick={this.handleClick} href={number} key={number} id={number}> {number} </PaginationLink> </PaginationItem> </Pagination> )} <PaginationItem> { currentPage === last ? <PaginationLink disabled>Next</PaginationLink> : <PaginationLink onClick={this.handleClick} id={pageNumbers[currentPage]} href={pageNumbers[currentPage]}>Next</PaginationLink> } </PaginationItem> <PaginationItem> { currentPage === last ? <PaginationLink disabled>Last</PaginationLink> : <PaginationLink onClick={this.handleLastClick} id={pageNumbers[currentPage]} href={pageNumbers[currentPage]}>Last</PaginationLink> } </PaginationItem> </Pagination> </nav> </ul> </div> ); } } ReactDOM.render( <SamplePagination />, document.getElementById('root') ); 
+2
source share

Here is a way to create your custom pagination component from the act-bootstrap lib library, and you can use this component throughout the project. enter image description here

Your pagination component (pagination.jsx or js)

 import React, { Component } from "react"; import { Pagination } from "react-bootstrap"; import PropTypes from "prop-types"; export default class PaginationHandler extends Component { constructor(props) { super(props); this.state = { paging: { offset: 0, limit: 10 }, active: 0 }; } pagingHandler = () => { let offset = parseInt(event.target.id); this.setState({ active: offset }); this.props.pageHandler(event.target.id - 1); }; nextHandler = () => { let active = this.state.active; this.setState({ active: active + 1 }); this.props.pageHandler(active + 1); }; backHandler = () => { let active = this.state.active; this.setState({ active: active - 1 }); this.props.pageHandler(active - 1); }; renderPageNumbers = (pageNumbers, totalPages) => { let { active } = this.state; return ( <Pagination> <Pagination.Prev disabled={active < 5} onClick={ active >5 && this.backHandler} /> { pageNumbers.map(number => { if ( number >= parseInt(active) - 3 && number <= parseInt(active) + 3 ) { return ( <Pagination.Item id={number} active={number == active} onClick={this.pagingHandler} > {number} </Pagination.Item> ); } else { return null; } })} <Pagination.Next onClick={ active <= totalPages -4 && this.nextHandler} /> </Pagination> ); }; buildComponent = (props, state) => { const { totalPages } = props; const pageNumbers = []; for (let i = 1; i <= totalPages; i++) { pageNumbers.push(i); } return ( <div className="pull-right"> {this.renderPageNumbers(pageNumbers ,totalPages)} </div> ); }; render() { return this.buildComponent(this.props, this.state); } } PaginationHandler.propTypes = { paging: PropTypes.object, pageHandler: PropTypes.func, totalPages: PropTypes.object }; 

Using the above component in your component

 import Pagination from "../pagination"; pageHandler = (offset) =>{ this.setState(({ paging }) => ({ paging: { ...paging, offset: offset } })); } render() { return ( <div> <Pagination paging = {paging} pageHandler = {this.pageHandler} totalPages = {totalPages}> </Pagination> </div> ); } 
+1
source share

I recently created a library that helps you deal with pagination examples, for example:

  • saving normalized data in Redux
  • page caching based on search filters
  • simplified use of a virtualized answer list
  • refreshing results in the background
  • saving last visited page and used filters

The DEMO page implements all of the above functions.

You can find the source code on Github

0
source share

Inactive ReactJS component for rendering pagination. You can also use this library:

 https://www.npmjs.com/package/react-js-pagination 

Some examples here:

http://vayser.imtqy.com/react-js-pagination/

OR

You can also use this https://codepen.io/PiotrBerebecki/pen/pEYPbY

0
source share

Make sure you do this as a separate component. I used tabler-responsive

 import * as React from "react"; import { Page, Button } from "tabler-react"; class PaginateComponent extends React.Component { constructor(props) { super(props); this.state = { array: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], limit: 5, // optional page: 1 }; } paginateValue = (page) => { this.setState({ page: page }); console.log(page) // access this value from parent component } paginatePrevValue = (page) => { this.setState({ page: page }); console.log(page) // access this value from parent component } paginateNxtValue = (page) => { this.setState({ page: page }); console.log(page) // access this value from parent component } render() { return ( <div> <div> <Button.List> <Button disabled={this.state.page === 0} onClick={() => this.paginatePrevValue(this.state.page - 1)} outline color="primary" > Previous </Button> {this.state.array.map((value, index) => { return ( <Button onClick={() => this.paginateValue(value)} color={ this.state.page === value ? "primary" : "secondary" } > {value} </Button> ); })} <Button onClick={() => this.paginateNxtValue(this.state.page + 1)} outline color="secondary" > Next </Button> </Button.List> </div> </div> ) } } export default PaginateComponent; 
0
source share
 function Pagination(pageEleArr, numOfEleToDisplayPerPage) { this.pageEleArr = pageEleArr; this.numOfEleToDisplayPerPage = numOfEleToDisplayPerPage; this.elementCount = this.pageEleArr.length; this.numOfPages = Math.ceil(this.elementCount / this.numOfEleToDisplayPerPage); const pageElementsArr = function (arr, eleDispCount) { const arrLen = arr.length; const noOfPages = Math.ceil(arrLen / eleDispCount); let pageArr = []; let perPageArr = []; let index = 0; let condition = 0; let remainingEleInArr = 0; for (let i = 0; i < noOfPages; i++) { if (i === 0) { index = 0; condition = eleDispCount; } for (let j = index; j < condition; j++) { perPageArr.push(arr[j]); } pageArr.push(perPageArr); if (i === 0) { remainingEleInArr = arrLen - perPageArr.length; } else { remainingEleInArr = remainingEleInArr - perPageArr.length; } if (remainingEleInArr > 0) { if (remainingEleInArr > eleDispCount) { index = index + eleDispCount; condition = condition + eleDispCount; } else { index = index + perPageArr.length; condition = condition + remainingEleInArr; } } perPageArr = []; } return pageArr; } this.display = function (pageNo) { if (pageNo > this.numOfPages || pageNo <= 0) { return -1; } else { console.log('Inside else loop in display method'); console.log(pageElementsArr(this.pageEleArr, this.numOfEleToDisplayPerPage)); console.log(pageElementsArr(this.pageEleArr, this.numOfEleToDisplayPerPage)[pageNo - 1]); return pageElementsArr(this.pageEleArr, this.numOfEleToDisplayPerPage)[pageNo - 1]; } } } const p1 = new Pagination(['a', 'b', 'c', 'd', 'e', 'f', 'g'], 3); console.log(p1.elementCount); console.log(p1.pageEleArr); console.log(p1.numOfPages); console.log(p1.numOfEleToDisplayPerPage); console.log(p1.display(3)); 
0
source share

Give you the pagination component, which may be a little hard to understand for newbies to react :

https://www.npmjs.com/package/pagination

-3
source share

I published the component for pagination purposes only. There he is .

 npm install pagination-component --save 
-3
source share

All Articles