Masayan tech blog.

  1. ブログ記事一覧>
  2. react-paginateを使用してページネーション用コンポーネントを作成する

react-paginateを使用してページネーション用コンポーネントを作成する

公開日

環境

  • windows10
  • DockerDesktop for Win 3.5.x
  • node v14.17.4
  • npm 6.14.14
  • React 17.0.1
  • react-paginate 8.1.0
  • VsCode
  • gitbash 2.32.0.1

動作イメージ

イイ感じですね。サンプルなのでスタイルは最低限にしていますが、結構柔軟に充てれそうです。

設定手順

インストール

npm install react-paginate

ページネーション用コンポーネント

propsの全仕様については、公式を参照ください

Pagination.jsx

  • react-paginateをimport
  • 親コンポーネントからデータの総数、表示するデータの開始位置、1ページあたりの表示数のpropsを受け取る
  • データの総数を1ページに表示するデータ数で割り、総ページ数を計算する
  • ページクリック時のイベントを定義
    ・選択したページを受け取り、表示するデータが含まれるページの開始位置を更新する
    ・urlを修正する(?page=2)
import ReactPaginate from 'react-paginate'
import React from 'react'
import NumberUtil from '../../shared/function/Number/NumberUtil'

const Pagination = (props) => {
const { dataCounts, setStart, numberOfDisplaysPerpage, currentPage } = props
const totalPageCount = NumberUtil.roundByCeil(dataCounts, numberOfDisplaysPerpage)

// ページクリック時のイベント
const handlePaginate = (selectedPage) => {
  // selectedPage.selectedには、ページ番号 - 1が入る
  const page = selectedPage.selected * numberOfDisplaysPerpage
  setStart(page)
  history.pushState({}, '', `?page=${selectedPage.selected + 1}`)
}

return (
  <ReactPaginate
    forcePage={currentPage} // 現在のページをreactのstateで管理したい場合等
    pageCount={totalPageCount}
    onPageChange={handlePaginate}
    marginPagesDisplayed={4} // 先頭と末尾に表示するページ数
    pageRangeDisplayed={2} // 現在のページの前後をいくつ表示させるか
    containerClassName="pagination justify-center" // ul(pagination本体)
    pageClassName="page-item" // li
    pageLinkClassName="page-link rounded-full" // a
    activeClassName="active" // active.li
    activeLinkClassName="active" // active.li < a
    
    // 戻る・進む関連
    previousClassName="page-item" // li
    nextClassName="page-item" // li
    previousLabel={'<'} // a
    previousLinkClassName="previous-link"
    nextLabel={'>'} // a
    nextLinkClassName="next-link"
   
    // 先頭 or 末尾に行ったときにそれ以上戻れ(進め)なくする
    disabledClassName="disabled-button d-none"
   
    // 中間ページの省略表記関連
    breakLabel="..."
    breakClassName="page-item"
    breakLinkClassName="page-link"
  />
)
}

export default Pagination

pagination.css

.pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 10px;
    gap: 20px 6px;
}


.page-item,
.page-link {
    display: inline-flex;
    align-items: center;
    border-radius: 30px;
    justify-content: center;
    font-weight: 700;
    font-size: 16px;
    height: 40px;
    width: 40px;
}

ユーティリティ関数

生成するページ数の計算用

class NumberUtil {

    // 引数の数以上の最小の整数を返します(四捨五入なしの無条件切り上げ)
    static roundByCeil = (numerator, denominator) => {
        return Math.ceil(numerator / denominator)
    }
}

export default NumberUtil

ページネーション表示用コンポーネント

SomethingPage.jsx

  • Pagination.jsxにデータの総数、表示するデータの開始位置、1ページあたりの表示数をpropsでわたす
...割愛
return (
  ...

  // データ表示用コンポーネント
  <Table
    {...{
      start,
      numberOfDisplaysPerpage
    }}
  />  

  // ページネーション
  <BasicContainer className="container-stock__pagination mt-4">
    <Pagination
      dataCounts={stocks.length}
      setStart={setStart}
      numberOfDisplaysPerpage={numberOfDisplaysPerpage}
      currentPage={currentPage}
    />
  </BasicContainer>
...割愛

データ表示用コンポーネント

Table.jsx

  • sliceで選択したページに対応するデータを切り取り、表示する
    slice(全データから切り取る開始位置, そこから取得するデータの数)
return (
  <table class="min-w-full">
    <thead class="bg-black-thin text-whi">
      <THeaderRow headerList={props.headerList} className={'p-10'} />
    </thead>
    <tbody class="bg-black-thin">
      {props.stocks.slice(props.start, props.start + props.numberOfDisplaysPerpage)
      .map((data) => ( 
        <tr>
          <TData
      ...割愛

以上です。

まとめ

いかがでしたでしょうか。本記事では、react-paginateを使用してページネーション用コンポーネントを作成する方法について紹介しています。導入がとても簡単で、使用する際もReactPaginateコンポーネントに所定の値を渡すだけでレンダリングできます。また、スタイリングなども簡単でカスタマイズが柔軟にできるのでお勧めです。