「Material-UI Pagination」等で調べると、
最初に出てくるのがMaterial-UIが用意してくれている「TablePagination API - Material-UI」です。
見た目はこんな感じ。
(デモコード)
結構スタイルが限られてしまってるので、良さそうなライブラリを見つけました!
material-ui-flat-pagination - npm
material-ui-flat-pagination
で実際に実装したメモを残すことにします。
前準備
Material-UIを使用しているのを前提に進めていきます!
まずは公式ドキュメント通り、インストールしていきましょう。
$ npm install material-ui-flat-pagination
また、公式ドキュメントにある createMuiTheme
, MuiThemeProvider
系の説明は「Theme」にあります♫👀
いざ、実装
material-ui-flat-pagination
のドキュメントを見る限り、めっちゃ簡単そうです!
1.import
してとりあえずタグを置いてみる
Exampleに書いてある通りにimportし、<Pagination />
タグを設置していこうと思います。
コンポーネントのimport群に下を追加します。
import Pagination from "material-ui-flat-pagination";
ローカルステートにページャーに必要なoffset
と、1ページに表示させる数n個を指定します。
class Example extends React.Component {
constructor(props) {
super(props)
this.state = {
...
offset: 0,
parPage: 10,
...
}
}
...
}
今回はリスト10個ずつ表示されるよう、perPage: 10
を設定してみました。
お次に<Pagination />
とonClick
時の関数handleClickPagination
を実装していきます!
...
handleClickPagination = offset => {
this.setState({ offset })
}
render() {
return (
<div>
<ul>
{this.state.userList
.slice(offset, offset + parPage)
.map(user => {
<li>{user.id}: {user.name}</li>
})
}
</ul>
<Pagination
limit={this.state.parPage}
offset={this.state.offset}
total={this.state.userList.length}
onClick={(e, offset) => this.handleClickPagination(offset)}
/>
</div>
)
}
...省略
こんな感じでしょうか!
total
にはループ表示したいリストの総数を入れます。なのでtotal={配列.length}
と入れてあげればOKです。
スタイルをつけてないと、デフォルトだとこんな感じです。
画像元:npm material-ui-flat-pagination
あとは軽くcssで肉付けして完了です。
2.スタイル調整していい感じにする
classes
でクラス名を指定し、また、リストが10個以下の時はページャーを表示させたくなかったので、length > 10
で囲っています。
pageNavi: {
textAlign: 'center',
'& > button': {
width: 50,
height: 50,
margin: '0 5px',
borderRadius: 5,
border: '1px solid gray'
}
},
pageNaviCurrent: {
cursor: 'default',
backgroundColor: 'yellow',
'&:hover': {
backgroundColor: 'yellow'
}
},
pageNaviText: {
color: 'black'
},
pageNaviStandard: {
'&:hover': {
backgroundColor: 'rgba(0, 0, 0, 0.08)'
}
},
pageNaviArrow: {
'&:hover': {
backgroundColor: 'rgba(0, 0, 0, 0.08)'
}
}
const { userList, parPage, offset } = this.state
{userList.length > parPage && (
<Pagination
limit={parPage}
offset={offset}
total={userList.length}
onClick={(e, offset) => this.handleClickPagination(offset)}
className={classes.pageNav}
classes={{
rootStandard: classes.pageNaviStandard,
rootCurrent: classes.pageNaviCurrent,
rootEnd: classes.pageNaviArrow,
text: classes.pageNaviText
}}
/>
)}
ボタンっぽくしたかったのでborderつけたり、width、height指定したりたりしています。
3.ループさせた時のイベント処理
ループさせている各リストごとに、例えば「編集」や「削除」ボタンがあって操作させる時、順番を取ることがあると思います。
例)
<ul>
{this.state.userList
.slice(offset, offset + parPage)
.map((user, i) => {
<li>
{user.id}: {user.name}
<Button
onClick={e => this.handleClickEdit(i, e)}
>
編集
</Button>
<Button
onClick={e => this.handleClickRemove(i, e)}
>
削除
</Button>
</li>
})
}
</ul>
offset
は、2ページ目以降のindex
は現在表示されているリストの上から何番目かを取得しています。
取得した全データをローカルステートに入れていると、ページ送りした分+ページ上から数えて何個目かを指定する必要があります。offset
は「nページ目 × 1ページに表示させる個数」なので、indexは下のように取得できます。
handleClickEdit = (i, e) => {
const users = this.state.userList
const index = this.state.offset + i
users[index].name = e.target.value
this.setState({
userList: users
})
}
簡単です!
終わりに
Material-UIデフォルトでこのページネーションがあれば良いのにと思いましたが、material-ui-flat-paginationを使って簡単に実装できたので、とても有効的だと思いました。