LoginSignup
13
13

More than 5 years have passed since last update.

material-ui-flat-paginationを使ってページネーションを実装する

Posted at

「Material-UI Pagination」等で調べると、
最初に出てくるのがMaterial-UIが用意してくれている「TablePagination API - Material-UI」です。
見た目はこんな感じ。

1.png

デモコード

結構スタイルが限られてしまってるので、良さそうなライブラリを見つけました!
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です。
スタイルをつけてないと、デフォルトだとこんな感じです。

demo.gif

画像元: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を使って簡単に実装できたので、とても有効的だと思いました。

13
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
13