こんにちは!react初心者のりすです。
pokeAPIでポケモン図鑑を作っています。
ページネーションの実装に初めてreact-pagenateを使ったので、その手順をまとめてみました。
作ったもの
https://risu043.github.io/pokemon-ja/
ページネーション導入手順
まずはreact-pagenateをインストールします。
npm install react-paginate
次に、ページネーションを導入したいコンポーネントにインポートします。
import ReactPaginate from 'react-paginate';
ページネーションを表示させたい場所にReactPaginateを置きます。
<ReactPaginate
breakLabel="..."
nextLabel="next >"
onPageChange={handlePageClick}
pageRangeDisplayed={5}
pageCount={pageCount}
previousLabel="< previous"
renderOnZeroPageCount={null}
/>
pageCount(総ページ数)を設定するとブラウザにページネーションを表示されます。
ページネーションをクリックすると、そのページに対応するインデックス番号を
handlePageClick関数の中で受け取れるようになっています。
const handlePageClick = async (data: { selected: number }): Promise<void> => {
// 2ページ目をクリックすると、コンソールに「1」と表示される
console.log(data.selected);
};
handlePageClickで受け取ったインデックス番号をもとに、配列全体から必要な部分をsliceして、map関数にセットするとページネーションが機能します!
…ところが、pokeAPIから全てのポケモンの日本語データを1回で取得することはできません。(リクエストが多すぎてエラーが生じてしまいます)
そこで、任意の開始位置から一定数のポケモンのみ取得できるよう工夫します。
const res = await fetch('https://pokeapi.co/api/v2/pokemon');
上記の場合、図鑑番号1のフシギダネから20匹のポケモンのデータを取得できます。
ここで、fetchするurlにlimit(取得したいポケモンの数)とoffset(開始位置)を付け足します。
下記の場合、図鑑番号21のオニスズメから20匹のポケモンデータを取得できます。
const res = await fetch('https://pokeapi.co/api/v2/pokemon?limit=20&offset=20');
url中のlimitとoffsetを変数に置き換えます。
const res = await fetch(`https://pokeapi.co/api/v2/pokemon?limit=${limit}&offset=${offset}`);
offsetはページのインデックス番号とlimit(取得したいポケモンの数)の積で求めます。
よって、ページネーションをクリックした時の処理は下記のように記述できます。
const handlePageClick = async (data: { selected: number }): Promise<void> => {
let limit = 20;
let offset: number = data.selected * limit;
const res = await fetch(
`https://pokeapi.co/api/v2/pokemon?limit=${limit}&offset=${offset}`
);
const data = await res.json();
// ここでdataをstateにセットします
};
これで、好きなページの20匹分だけデータを取得できました!
戻り値をmap関数にセットして、ページネーション付きのポケモン図鑑の完成です。
まとめ
初心者なので配列の操作や非同期関数でつまづきがちでしたが、
図鑑作りに熱中しているうちに少し理解できたような気がします。
コード全体をgithubに載せています。一緒にポケモン図鑑を作りましょう!
https://github.com/risu043/pokemon-ja