😊
Reactでページネーションを作る
※私は文系エンジニアなのであんまり数学の知識がありません。所々式が脳筋かも知れませんが式は適時いいものに変えてください。
今回は見やすさという観点でのページネーションなので、大量のデータがあると表示速度が遅くなってしまうと思います。データが大量にある時はその時に合わせていい感じに実装することをお勧めします。
まずは配列にする
まずは表示させたいデータを配列の形式にします。
配列を切り分ける関数を作る
私はこんな式で強引?に切り分けています。今回はアルゴリズムの説明がメインではないのでコメントアウトで簡単に説明しておきます。とにかく、表示したい個数単位分に切り分ける関数が作れればいいです。
//cutNumberには何個単位で表示するかの数字を入力
function splitArray(array,cutNumber) {
const newArr = [];
//配列の先頭に0を追加
array.unshift(0);
//ページ数になるまで配列を切って新しい配列newArrayにいれる
for(let i =1; i < Math.floor(array.length); i+=cutNumber){
newArr.push(array.slice(i,i+cutNumber));
}
return newArr;
}
新しい配列を展開する
ex)
const array = [1,2,3,4,5,6,7];
splitArray(array,3)
//とすると… 返ってくるのは
[
[1,2,3],
[4,5,6],
[7
]
//となっているはずなので、、、
これを以下のように展開します。
ただこのままでは余裕でエラーが起こります。
{posts.map((post, i) =>
<li key={i}>
<p>{post}</p>
</li>)
}
ページ管理
次に今のページを管理する関数を作ります。
const [page,setPage] = useState(0);
const handlePage = (e)=>{
const type = e.target.value;
if(type === 'before'){
setPage(page-1);
return;
}
setPage(page+1)
return;
}
(中略)
return(
<ul>
{posts.map((post, i) =>
<li key={i}>
<p>{post}</p>
</li>)
}
</ul>
<button onClick={handlePage} value='before'>前へ</button>
<button onClick={handlePage} value='next'>次へ</button>
)
こんな感じ
ページで展開する配列を変える
(中略)
return(
//ここにpostsの何ページ目(切り分けた配列の何個目)を展開するか指定するため[page]を追加
{posts[page].map((post, i) =>
<li key={i}>
<p>{post}</p>
</li>)
}
<button onClick={handlePage} value='before'>前へ</button>
<button onClick={handlePage} value='next'>次へ</button>
)
ボタンを制御
このままでは切り分けた配列以上ページ数が増えたり減ったりしてしまうので、ページ数が0の時は「前へ」を隠して、ページ数が切り分けた配列の長さ以上になってしまう時は「次へ」を隠します。
(略)
return(
(略)
{page > 0 ? <button onClick={handlePage} value='before'>前へ</button> : ''}
{page === posts.length-1 ? '' : <button onClick={handlePage} value='next'>次へ</button> }
)
完成!全体としてはこんな感じ
import React, { useState } from 'react'
function Yeah() {
const [posts,setPosts] = useState();
const [page,setPage] = useState(0);
const handlePage = (e)=>{
const type = e.target.value;
if(type === 'before'){
setPage(page-1);
return;
}
setPage(page+1)
return;
}
const splitArray = (array,cutNumber)=>{
const newArr = [];
array.unshift(0);
for(let i =1; i < Math.floor(array.length); i+=cutNumber){
newArr.push(array.slice(i,i+cutNumber));
}
return newArr;
}
return (
<div>
<ul>
{posts[page].map((post, i) =>
<li key={i}>
<p>{post}</p>
</li>)
}
</ul>
{page > 0 ? <button onClick={handlePage} value='before'>前へ</button> : ''}
{page === posts.length-1 ? '' : <button onClick={handlePage} value='next'>次へ</button> }
</div>
)
}}
}
終わりです!
Discussion
@mui/material
ライブラリから提供されているusePagination
フックを使ってデモを作ってみました。簡単ですが、以上です。