ReactでPaginationを実装する(material-ui)

#はじめに
10件のアイテムを1ページあたり3件、計4ページに渡って表示するサンプルです。

#実装
###サンプルアイテム

```javascript
const items = [
  {
    id: '1',
    name: 'abe',
    from: 'nagoya'
  },
  {
    id: '2',
    name: 'ito',
    from: 'iwate'
  },
  {
    id: '3',
    name: 'uno',
    from: 'fukuoka'
  },
  {
    id: '4',
    name: 'kato',
    from: 'tokyo'
  },
  {
    id: '5',
    name: 'kurata',
    from: 'tottori'
  },
  {
    id: '6',
    name: 'sato',
    from: 'kagoshima'
  },
  {
    id: '7',
    name: 'takahashi',
    from: 'saitama'
  },
  {
    id: '8',
    name: 'nishida',
    from: 'miyagi'
  },
  {
    id: '9',
    name: 'hasegawa',
    from: 'gifu'
  },
  {
    id: '10',
    name: 'yamada',
    from: 'aomori'
  }
]
```


###本体

```javascript
import React, { useState, useEffect } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import {
  List,
  ListItem,
  ListItemText,
  ListItemAvatar,
  Avatar,
  Typography
} from '@material-ui/core';
import Pagination from '@material-ui/lab/Pagination';


const useStyles = makeStyles((theme) => ({
  list: {
    width: '100%',
    maxWidth: 360,
    backgroundColor: theme.palette.background.paper,
  },
  pagenation: {
    '& > *': {
      marginTop: theme.spacing(2),
      display: 'inline-block',
    }
  },
  }));

const ListView = () => {

  const classes = useStyles();

  const [page, setPage] = useState(1); //ページ番号
  const [pageCount, setPageCount] = useState(); //ページ数
  const [allItems, setAllItems] = useState([]); //全データ
  const [displayedItems, setDisplayedItems] = useState([]); //表示データ
  const displayNum = 3; //1ページあたりの項目数

  const items = [...]


  useEffect(() => {
    setAllItems(items);
    //ページカウントの計算（今回は3項目/ページなので4ページ）
    setPageCount(Math.ceil(items.length/displayNum));
    //表示データを抽出
    setDisplayedItems(items.slice(((page - 1) * displayNum), page * displayNum))
  }, [])

  const handleChange = (event, index) => {
    //ページ移動時にページ番号を更新
    setPage(index);
    //ページ移動時に表示データを書き換える
    setDisplayedItems(allItems.slice(((index - 1) * displayNum), index * displayNum))
  }

  return (
    <>
      <List dense className={classes.list}>
        {displayedItems.map((item, index) => {
          const labelId = `label-${item.id}`;
          return (
            <ListItem key={index} button>
              <ListItemAvatar>
                <Avatar alt={item.name} src="/static/images/avatar/xxx.jpg" />
              </ListItemAvatar>
              <ListItemText
                id={labelId}
                primary={item.name}
                secondary={
                  <>
                    <Typography
                      component="span"
                      variant="caption"
                      display="block"
                      color="textPrimary"
                    >
                      {item.from}
                    </Typography>
                  </>
                } />
            </ListItem>
          );
        })}
      </List>
      <div className={classes.pagenation} style={{textAlign:'center'}}>
        <Pagination count={pageCount} page={page} variant="outlined" color="primary" size="small" onChange={handleChange} />
      </div>
    </>
  )
}

export default ListView;
```

#実行結果

![スクリーンショット 2021-03-06 20.58.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664031/9c85bb2c-a513-e499-63cc-2cbff4e7acdc.png)