2016-10-25 3 views
7

Я новичок в ReactJS и создаю в нем простое приложение TODO. На самом деле, это очень простое приложение без соединения db, задачи хранятся в массиве. Я добавил в него функцию редактирования и удаления. Теперь я хочу добавить разбивку на страницы. Как его реализовать? Любая помощь будет оценена. Спасибо...!!как реализовать Pagination in reactJs

+0

Вы можете произвести поиск ключевого слова 'reactjs todo' в Github. Вы получите много образцов. Я предлагаю вам изучить их сначала. –

+0

. Я назвал это для вышеуказанных функций. но для разбивки на страницы я не нашел там никакой помощи. – Nitesh

ответ

28

Я реализовал пагинацию в чистом Реагировать JS недавно. Вот рабочая демонстрация: http://codepen.io/PiotrBerebecki/pen/pEYPbY

Вам, конечно же, придется отрегулировать логику и отобразить номера страниц, чтобы они соответствовали вашим требованиям.

Полный код:

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') 
); 
+1

Спасибо, Петр Беребекки. Это самый простой и лучший ответ. Спасибо тонне ... !!! – Nitesh

+0

Другие руки по учебнику по созданию разбитого списка в React: https://www.robinwieruch.de/react-paginated-list/ –

-1

Дай вам компонент постраничной, который может быть немного трудно понять, для новичка в react:

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

+0

Yah .. Это немного сложно для новичка. в любом случае спасибо за вашу помощь .. :-) – Nitesh

-2

Я опубликовал компонент только для целей пагинацией. Here it is.

npm install pagination-component --save 
1

Недавно я создал этот PAGINATION компонент, который реализует логику пейджинга как результаты поиска Google:

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; 

А вот компонент App примера, который использует компонент PAGINATION для постраничного списка из 150 примеров пунктов:

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; 

Для получения более подробной информации и демо вы можете проверить this post

+1

Не было бы лучше использовать что-то вроде https://www.npmjs.com/ package/response-js-pagination вместо того, чтобы изобретать колесо? –

0
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

Я недавно создал библиотеку, которая помогает справиться с делами постраничной как:

  • хранящих нормированные данные в Redux
  • кэширования страниц на основе поисковых фильтров
  • упрощенный использование реагировать-виртуализированных список
  • Обновляемые результаты в фоновом режиме
  • хранение последней посещенной страницы и использованных фильтров

DEMO страница реализует все вышеуказанные функции.

Исходный код можно найти на Github

0

Я попытался воссоздать простой пример постраничной дается piotr-berebecki, который был большим. Но когда будет много страниц, разбиение на страницы будет переполняться на экране. Таким образом, я использовал кнопку «предыдущий» и «Назад» вместе с кнопкой «вперед» и «назад», чтобы перемещаться вперед и назад между страницами. И для конструктивной части я использовал бутстрап 3.

Вы можете настроить количество страниц для отображения в разбивке по страницам с использованием значений, связанных с страницей. Не забудьте использовать одно и то же значение для upperPageBound и 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') 
     ); 

Работа демо ссылка: https://codepen.io/mhmanandhar/pen/oEWBqx

Изображение: simple react pagination