material-ui-flat-pagination을 사용하여 페이지네이션 구현

「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 를 사용해 간단하게 구현할 수 있었으므로, 매우 유효하다고 생각했습니다.

좋은 웹페이지 즐겨찾기