環境
- 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コンポーネントに所定の値を渡すだけでレンダリングできます。また、スタイリングなども簡単でカスタマイズが柔軟にできるのでお勧めです。