ページネーション。
サイトで複数のページがあったら出てくるやつです。
ReactPaginateを使えば簡単にできました。
こういうのを作っていきたいと思います。
1からでも表示出来るよう、create-react-appも叩きます。
ReactPaginate がすぐ使いたければコードの方へ飛んでください。
create-react-app
適当な場所にappフォルダを作成してcreate-react-appしたいと思います。
$ mkdir app
$ create-react-app app
create-react-appは少し時間がかかります。。
Success!メッセージが表示されていれば無事にフォルダが出来たと思います。
app
├── public
└── src
├── App.css
├── App.js
├── index.js
└── その他省略...
ターミナルのディレクトリを移動しておきます。
$ cd ./app
Paginate.jsファイルを作成しておきます。こちらにReactPaginateのコードを書く予定です。
$ touch ./src/Paginate.js
これでフォルダの準備が出来ました。
必要なモジュールをnpm install
※ ターミナルはcreate-react-appで作成したappにいる想定です。。
今回使うのは、react-paginateです。
npm installします。
$ npm install --save react-paginate
これは今回はあまり必要ないですが、
bootstrapもnpm installしておきます。
$ npm install --save react-bootstrap bootstrap@3
これで前準備が出来ました。コードの方を書いていきます。
コード
app/src/Paginate.js
import ReactPaginate from 'react-paginate';
let setStateOfSelectPage;
const Paginate = (props) => {
const { listLength, displayCount, setStateInfoAction } = props;
setStateOfSelectPage = setStateInfoAction;
return (
<>
<ReactPaginate
style={{ marginTop: 10, marginBottom: 100 }}
pageCount={pageCountCalc(listLength, displayCount)}
marginPagesDisplayed={5}
pageRangeDisplayed={10}
onPageChange={handlePageClick}
containerClassName='pagination'
pageClassName='page-item'
pageLinkClassName='page-link'
activeClassName='active'
previousLabel='<'
nextLabel='>'
previousClassName='page-item'
nextClassName='page-item'
previousLinkClassName='page-link'
nextLinkClassName='page-link'
disabledClassName='disabled'
breakLabel='...'
breakClassName='page-item'
breakLinkClassName='page-link'
/>
</>
);
}
const handlePageClick = page => {
setStateOfSelectPage(page.selected, 'selectPage');
window.scrollTo(0, 50);
};
const pageCountCalc = (len, count) => {
if (len < count) {
return 1;
}
return Math.ceil(len / count);
};
export default Paginate;
app/src/App.js
import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import Paginate from './Paginate';
// test用表示データ作成数
const CREATE_INFO = 50;
// test用固定データ
const INFO = {
a: 'aaa',
b: 'bbb',
c: 'ccc'
};
// 1ページの表示件数
const DISPLAY_COUNT = 5;
export class App extends React.Component {
constructor(props) {
super(props);
this.state = {
selectPage: 0,
displayCount: DISPLAY_COUNT
};
}
render() {
const infoList = createInfoList(CREATE_INFO);
const { selectPage, displayCount } = this.state;
const end = (selectPage+1) * displayCount;
const start = end - displayCount;
const displayInfoList = infoList.slice(start, end);
return (
<div className='App'>
<div className='text-center'>
<h1>ページネーション</h1>
</div>
<div className='container'>
{ displayInfoList && displayInfoList.map((info, index) => {
return (
<div key={start + index}>
<div>index: {start + index + 1}</div>
<div>a: {info.a}</div>
<div>b: {info.b}</div>
<div>c: {info.c}</div>
<div>----------</div>
</div>
);
})}
<Paginate
listLength={infoList.length}
displayCount={displayCount}
setStateInfoAction={this.setStateInfoAction}
/>
</div>
</div>
);
};
setStateInfoAction = (value, type) => {
switch(type) {
case 'selectPage':
this.setState({ ...this.state, selectPage: value });
break;
default:
break;
}
};
}
// test用List作成
const createInfoList = num => {
let infoList = [];
for (let count=0; count < num; count++) {
infoList.push(INFO)
}
return infoList;
}
export default App;
動作確認をしてみよう
実際に動かしてみましょう。
$ yarn start
無事に動けば、http://localhost:3000 にChrome等でアクセスしましょう。
画面はこんな感じです。
2ページ目に移動します。
ページ移動ができ、表示が変わっていれば成功です。
所感
簡単に使う分の動きは問題ない感じです。
細かいところをいうと
・1ページ目の時は「<」の戻るボタンが不要
・ページが1ページしかない時はPaginateを出す必要がない
といった細かい修正は必要でしょうか。(他にもあるかもですが)
気にならないっちゃ気にならないですが。。
以上、「ReactPaginateを使ってページ移動」でした。
コメント