how to implement Pagination in reactJs

后端 未结 10 1411
抹茶落季
抹茶落季 2020-11-28 02:05

I am new to ReactJS and am creating a simple TODO application in it. Actually, it is a very basic app with no db connection, tasks are stored in an array. I added Edit and D

相关标签:
10条回答
  • 2020-11-28 02:46

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

    You would of course have to adjust the logic and the way page numbers are displayed so that it meets 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')
    );
    
    0 讨论(0)
  • 2020-11-28 02:56

    Here is a way to create your Custom Pagination Component from react-bootstrap lib and this component you can use Throughout your project

    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 
       };
    

    Use of 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>
        );
      }
    
    0 讨论(0)
  • 2020-11-28 02:57

    I recently created this Pagination component that implements paging logic like Google's 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's an example App component that uses the Pagination component to paginate a list of 150 example items:

    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 details and a live demo you can check out this post

    0 讨论(0)
  • 2020-11-28 03:00

    I've recently created library which helps to cope with pagination cases like:

    • storing normalized data in Redux
    • caching pages based on search filters
    • simplified react-virtualized list usage
    • refreshing results in background
    • storing last visited page and used filters

    DEMO page implements all above features.

    Source code you can find on Github

    0 讨论(0)
  • 2020-11-28 03:02
       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')
        );
    
    0 讨论(0)
  • 2020-11-28 03:07

    Make sure you make it as a separate component I have used tabler-react

    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 讨论(0)
提交回复
热议问题