over 3 years ago

練習編寫 React 分頁 component

建立 Component\Pagination.js

import React, {Component, PropTypes} from 'react';

class Pagination extends Component {
  constructor(props) {
    super(props);
  }
  _bindFirstPage() {
    if (this.props.currentPage != 1 && this.props.isSetFirst == true) {
      return <a id={'page_1'}
                    style={this.props.linkStyle}
                    href="#"
                    onClick={this.props.onClick.bind(this, 1)}>{this.props.firstDesc}</a>;
    }
  }
  _bindLastPage() {
    if (this.props.currentPage != this.props.sumPages && this.props.isSetLast == true) {
      return <a id={'page_' + this.props.sumPages}
                    style={this.props.linkStyle}
                    href="#"
                    onClick={this.props.onClick.bind(this, this.props.sumPages)}>{this.props.lastDesc}</a>;
    }
  }
  _bindPrePage() {
    if (this.props.currentPage != 1 && this.props.isSetPre == true) {
        var pageNum = parseInt(this.props.currentPage) - 1;
        return <a id={'page_' + pageNum}
                      style={this.props.linkStyle}
                      href="#"
                      onClick={this.props.onClick.bind(this, pageNum)}>{this.props.preDesc}</a>;
    }
  }
  _bindNextPage() {
      if (this.props.currentPage != this.props.sumPages && this.props.isSetNext == true) {
          let pageNum = parseInt(this.props.currentPage) + 1;
          return <a id={'page_' + pageNum}
                        style={this.props.linkStyle}
                        href="#"
                        onClick={this.props.onClick.bind(this, pageNum)}>{this.props.nextDesc}</a>;
      }
  }
  _bindPreDesc(startPage) {
      if (startPage > 1 && this.props.isSetPreAndNextDesc == true) {
         return <span style={this.props.spanStyle}>{this.props.preAndNextDesc}</span>;
      }
  }
  _bindNextDesc(endPage) {
      if (endPage < this.props.sumPages && this.props.isSetPreAndNextDesc == true) {
          return <span style={this.props.spanStyle}>{this.props.preAndNextDesc}</span>;
      }
  }
  _bindPages(startPage, endPage) {
      let link = [];
      for (var pagenum = startPage; pagenum <= endPage; pagenum++) {
          if (pagenum == this.props.currentPage) {
             link.push(<span style={this.props.spanStyle}>{pagenum}</span>);
          } else {
            link.push(<a id={'page_' + pagenum}
                                style={this.props.linkStyle}
                                href="#"
                                onClick={this.props.onClick.bind(this, pagenum)}>{pagenum}</a>);
          }
      }
      return link;
  }
  render() {
    let startPage = 1;
    let endPage = 1;

    startPage = this.props.currentPage - parseInt(this.props.pageSize / 2);
    if (this.props.currentPage == this.props.sumPages) {
        startPage = this.props.sumPages - this.props.pageSize + 1;
    }
    if (this.props.currentPage == 1) {
        startPage = 1;
    }
    if (startPage < 1) {
        startPage = 1;
    }
    endPage = startPage + this.props.pageSize - 1;

    if (endPage > this.props.sumPages) {
        startPage -=  endPage - this.props.sumPages;
        endPage = this.props.sumPages;
    }

    if (startPage < 1) {
        startPage = 1;
    }
    let firstPage = this._bindFirstPage();
    let prePage = this._bindPrePage();
    let preDesc = this._bindPreDesc(startPage);
    let bindPages = this._bindPages(startPage, endPage);
    let nextDesc = this._bindNextDesc(endPage);
    let nextPage = this._bindNextPage();
    let lastPage = this._bindLastPage();
    return (
      <div>
        {firstPage}
        {prePage}
        {preDesc}
        {bindPages}
        {nextDesc}
        {nextPage}
        {lastPage}
        </div>
    );
  }
}

Pagination.defaultProps = {
  sumPages: 30,
  currentPage: 5,
  pageSize:5,
  firstDesc: "第一頁",
  lastDesc: "最末頁",
  preDesc: "上一頁",
  nextDesc: "下一頁",
  preAndNextDesc: "...",
  isSetFirst: true,
  isSetLast: true,
  isSetPre: true,
  isSetNext: true,
  isSetPreAndNextDesc: true,
  linkStyle: {'marginRight':5},
  spanStyle: {'marginRight':5}
}

Pagination.propTypes = {
  sumPages: PropTypes.number.isRequired,
  currentPage: PropTypes.number.isRequired,
  pageSize:PropTypes.number.isRequired,
  firstDesc: PropTypes.string.isRequired,
  lastDesc: PropTypes.string.isRequired,
  preDesc: PropTypes.string.isRequired,
  nextDesc: PropTypes.string.isRequired,
  preAndNextDesc: PropTypes.string.isRequired,
  isSetFirst: PropTypes.bool.isRequired,
  isSetLast: PropTypes.bool.isRequired,
  isSetPre:PropTypes.bool.isRequired,
  isSetNext: PropTypes.bool.isRequired,
  isSetPreAndNextDesc: PropTypes.bool.isRequired,
  linkStyle: PropTypes.object.isRequired,
  spanStyle: PropTypes.object.isRequired
}

export default Pagination;

使用方式
於主 main 建立 _onClickLink 函數來控制 Pagination 的分頁狀態

import React, {Component, PropTypes} from 'react';
import ReactDOM from 'react-dom';
import Pagination from './Component/Pagination';

class Main extends Component {
  constructor(props) {
    super(props);
    this.state = {currentPage: 5, sumPages: 60};
    this._onClickLink =  this._onClickLink.bind(this);
  }
  _onClickLink(num, e) {
    // 接收 Pagination 所觸發的頁碼
    this.setState({currentPage: num, sumPages: 60});
  }
  render() {
    return(
      <div>
      <div><Pagination ref="Pagination" onClick={this._onClickLink} sumPages={this.state.sumPages}  currentPage={this.state.currentPage} /></div>
      <div><Pagination ref="Pagination2" onClick={this._onClickLink} pageSize={20} sumPages={this.state.sumPages}  currentPage={this.state.currentPage} /></div>
      </div>
    );
  }
}

ReactDOM.render(
    <Main />,
  document.getElementById('demo')
);

執行效果

← Webpack 啟用 Source Map 功能 開發階段時 Webpack 與 Server 端的整合配置 →
 
comments powered by Disqus