序章
多くの場合、リモートサーバー、API、またはデータベースから大量のデータレコードをフェッチする必要があるWebアプリケーションの構築に関与します。 たとえば、支払いシステムを構築している場合、何千ものトランザクションをフェッチしている可能性があります。 ソーシャルメディアアプリの場合、多くのユーザーコメント、プロファイル、またはアクティビティを取得している可能性があります。 いずれの場合でも、アプリを操作するエンドユーザーを圧倒しない方法でデータを表示するためのソリューションがいくつかあります。
大規模なデータセットを処理する1つの方法は、paginationを使用することです。 データセットのサイズ(データセット内のレコードの総数)が事前にわかっている場合、ページネーションは効果的に機能します。 次に、エンドユーザーとページネーションコントロールの相互作用に基づいて、データセット全体から必要なデータのチャンクのみをロードします。 これは、Google検索で検索結果を表示するために使用される手法です。
このチュートリアルでは、大規模なデータセットをページ付けするためにReactを使用してカスタムページ付けコンポーネントを構築する方法を学習します。 世界の国々のページ化されたビュー(既知のサイズのデータセット)を作成します。
これは、このチュートリアルで構築するもののデモです。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- ノードがマシンにインストールされています。 手順は、Node.jsをインストールしてローカル開発環境を作成する方法にあります。
- create-react-app コマンドラインパッケージを使用して、Reactアプリの定型コードを作成します。 使用している場合
npm < 5.2
、その後、インストールする必要があるかもしれませんcreate-react-app
グローバルな依存関係として。 - 最後に、このチュートリアルは、あなたがすでにReactに精通していることを前提としています。 そうでない場合は、 React.jsのコーディング方法シリーズをチェックして、Reactの詳細を確認してください。
このチュートリアルは、Nodev14.2.0で検証されました。 npm
v6.14.4、 react
v16.13.1、および react-scripts
v3.4.1。
ステップ1—プロジェクトの設定
を使用して新しいReactアプリケーションを開始します create-react-app
指図。 アプリケーションには好きな名前を付けることができますが、このチュートリアルでは名前を付けます react-pagination
:
- npx create-react-app react-pagination
次に、アプリケーションに必要な依存関係をインストールします。 まず、ターミナルウィンドウを使用して、プロジェクトディレクトリに移動します。
- cd react-pagination
次のコマンドを実行して、必要な依存関係をインストールします。
- npm install bootstrap@4.1.0 prop-types@15.6.1 react-flags@0.1.13 countries-api@2.0.1 node-sass@4.14.1
これによりインストールされます bootstrap
, prop-types
, react-flags
, countries-api
、 と node-sass
.
インストールしました bootstrap
デフォルトのスタイルが必要になるため、アプリケーションの依存関係としてパッケージ化します。 Bootstrapのスタイルも使用します pagination
成分。
アプリケーションにBootstrapを含めるには、 src/index.js
ファイル:
- nano src/index.js
そして、次の行を他の行の前に追加します import
ステートメント:
import "bootstrap/dist/css/bootstrap.min.css";
これで、Bootstrapスタイリングがアプリケーション全体で利用できるようになります。
また、インストールしました react-flags
アプリケーションの依存関係として。 アプリケーションからフラグアイコンにアクセスするには、アイコン画像をにコピーする必要があります。 public
アプリケーションのディレクトリ。
作成する img
あなたのディレクトリ public
ディレクトリ:
- mkdir public/img
で画像ファイルをコピーします flags
に img
:
- cp -R node_modules/react-flags/vendor/flags public/img
これにより、すべてのコピーが提供されます react-flag
アプリケーションへの画像。
いくつかの依存関係を含めたので、次のコマンドを実行してアプリケーションを起動します。 npm
から react-pagination
プロジェクトディレクトリ:
- npm start
アプリケーションを開始したので、開発を開始できます。 ライブリロード機能を備えたブラウザタブが開いており、開発中にアプリケーションとの同期を維持していることに注意してください。
この時点で、アプリケーションビューは次のスクリーンショットのようになります。
これで、コンポーネントの作成を開始する準備が整いました。
ステップ2—作成 CountryCard
成分
このステップでは、 CountryCard
成分。 The CountryCard
コンポーネントは、特定の国の名前、地域、および旗をレンダリングします。
まず、作成しましょう components
のディレクトリ src
ディレクトリ:
- mkdir src/components
次に、新しいを作成します CountryCard.js
のファイル src/components
ディレクトリ:
- nano src/components/CountryCard.js
そして、それに次のコードスニペットを追加します。
import React from 'react';
import PropTypes from 'prop-types';
import Flag from 'react-flags';
const CountryCard = props => {
const {
cca2: code2 = '', region = null, name = {}
} = props.country || {};
return (
<div className="col-sm-6 col-md-4 country-card">
<div className="country-card-container border-gray rounded border mx-2 my-3 d-flex flex-row align-items-center p-0 bg-light">
<div className="h-100 position-relative border-gray border-right px-2 bg-white rounded-left">
<Flag country={code2} format="png" pngSize={64} basePath="./img/flags" className="d-block h-100" />
</div>
<div className="px-3">
<span className="country-name text-dark d-block font-weight-bold">{ name.common }</span>
<span className="country-region text-secondary text-uppercase">{ region }</span>
</div>
</div>
</div>
)
}
CountryCard.propTypes = {
country: PropTypes.shape({
cca2: PropTypes.string.isRequired,
region: PropTypes.string.isRequired,
name: PropTypes.shape({
common: PropTypes.string.isRequired
}).isRequired
}).isRequired
};
export default CountryCard;
The CountryCard
コンポーネントには country
レンダリングされる国に関するデータを含む小道具。 に見られるように propTypes
のために CountryCard
コンポーネント、 country
propオブジェクトには、次のデータが含まれている必要があります。
cca2
–2桁の国コードregion
-国の地域(例:「アフリカ」)name.common
-国の一般名(例:「ナイジェリア」)
国オブジェクトのサンプルは次のとおりです。
{
cca2: "NG",
region: "Africa",
name: {
common: "Nigeria"
}
}
また、を使用して国旗をレンダリングする方法にも注目してください react-flags
パッケージ。 react-flagsのドキュメントをチェックして、必要な小道具とパッケージの使用方法の詳細を確認できます。
これで、個人が完成しました CountryCard
成分。 最終的には、 CountryCard
■アプリケーションにさまざまなフラグと国情報を表示するために複数回。
ステップ3—作成 Pagination
成分
このステップでは、 Pagination
成分。 The Pagination
コンポーネントには、ページネーションコントロールでページを作成、レンダリング、および切り替えるためのロジックが含まれています。
新しいを作成します Pagination.js
のファイル src/components
ディレクトリ:
- nano src/components/Pagination.js
そして、それに次のコードスニペットを追加します。
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
class Pagination extends Component {
constructor(props) {
super(props);
const { totalRecords = null, pageLimit = 30, pageNeighbours = 0 } = props;
this.pageLimit = typeof pageLimit === 'number' ? pageLimit : 30;
this.totalRecords = typeof totalRecords === 'number' ? totalRecords : 0;
// pageNeighbours can be: 0, 1 or 2
this.pageNeighbours = typeof pageNeighbours === 'number'
? Math.max(0, Math.min(pageNeighbours, 2))
: 0;
this.totalPages = Math.ceil(this.totalRecords / this.pageLimit);
this.state = { currentPage: 1 };
}
}
Pagination.propTypes = {
totalRecords: PropTypes.number.isRequired,
pageLimit: PropTypes.number,
pageNeighbours: PropTypes.number,
onPageChanged: PropTypes.func
};
export default Pagination;
The Pagination
コンポーネントは、で指定されているように4つの特別な小道具を取ることができます propTypes
物体。
onPageChanged
現在のページが変更された場合にのみ、現在のページ付け状態のデータで呼び出される関数です。totalRecords
ページ付けされるレコードの総数を示します。 必須です。pageLimit
1ページに表示されるレコード数を示します。 指定しない場合、デフォルトで30
で定義されているようにconstructor()
.pageNeighbours
現在のページの両側に表示する追加のページ番号の数を示します。 最小値は0
、および最大値は2
. 指定しない場合、デフォルトで0
で定義されているようにconstructor()
.
次の画像は、さまざまな値の効果を示しています pageNeighbours
小道具:
の中に constructor()
関数では、次のように合計ページを計算します。
this.totalPages = Math.ceil(this.totalRecords / this.pageLimit);
使用していることに注意してください Math.ceil()
ここで、総ページ数の整数値を確実に取得します。 これにより、特に超過レコードの数がページごとに表示されるレコードの数より少ない場合に、超過レコードが最後のページに確実にキャプチャされます。
最後に、状態を初期化しました currentPage
プロパティをに設定 1
. 現在アクティブなページを内部で追跡するには、この状態プロパティが必要です。
次に、ページ番号を生成するためのメソッドを作成します。
後に import
sしかし前に Pagination
クラス、次の定数を追加し、 range
関数:
// ...
const LEFT_PAGE = 'LEFT';
const RIGHT_PAGE = 'RIGHT';
/**
* Helper method for creating a range of numbers
* range(1, 5) => [1, 2, 3, 4, 5]
*/
const range = (from, to, step = 1) => {
let i = from;
const range = [];
while (i <= to) {
range.push(i);
i += step;
}
return range;
}
の中に Pagination
クラス、後 constructor
、以下を追加します fetchPageNumbers
方法:
class Pagination extends Component {
// ...
/**
* Let's say we have 10 pages and we set pageNeighbours to 2
* Given that the current page is 6
* The pagination control will look like the following:
*
* (1) < {4 5} [6] {7 8} > (10)
*
* (x) => terminal pages: first and last page(always visible)
* [x] => represents current page
* {...x} => represents page neighbours
*/
fetchPageNumbers = () => {
const totalPages = this.totalPages;
const currentPage = this.state.currentPage;
const pageNeighbours = this.pageNeighbours;
/**
* totalNumbers: the total page numbers to show on the control
* totalBlocks: totalNumbers + 2 to cover for the left(<) and right(>) controls
*/
const totalNumbers = (this.pageNeighbours * 2) + 3;
const totalBlocks = totalNumbers + 2;
if (totalPages > totalBlocks) {
const startPage = Math.max(2, currentPage - pageNeighbours);
const endPage = Math.min(totalPages - 1, currentPage + pageNeighbours);
let pages = range(startPage, endPage);
/**
* hasLeftSpill: has hidden pages to the left
* hasRightSpill: has hidden pages to the right
* spillOffset: number of hidden pages either to the left or to the right
*/
const hasLeftSpill = startPage > 2;
const hasRightSpill = (totalPages - endPage) > 1;
const spillOffset = totalNumbers - (pages.length + 1);
switch (true) {
// handle: (1) < {5 6} [7] {8 9} (10)
case (hasLeftSpill && !hasRightSpill): {
const extraPages = range(startPage - spillOffset, startPage - 1);
pages = [LEFT_PAGE, ...extraPages, ...pages];
break;
}
// handle: (1) {2 3} [4] {5 6} > (10)
case (!hasLeftSpill && hasRightSpill): {
const extraPages = range(endPage + 1, endPage + spillOffset);
pages = [...pages, ...extraPages, RIGHT_PAGE];
break;
}
// handle: (1) < {4 5} [6] {7 8} > (10)
case (hasLeftSpill && hasRightSpill):
default: {
pages = [LEFT_PAGE, ...pages, RIGHT_PAGE];
break;
}
}
return [1, ...pages, totalPages];
}
return range(1, totalPages);
}
}
ここでは、最初に2つの定数を定義します。 LEFT_PAGE
と RIGHT_PAGE
. これらの定数は、それぞれ左右に移動するためのページコントロールがあるポイントを示すために使用されます。
ヘルパーも定義しました range()
数値の範囲を生成するのに役立つ関数。
注:プロジェクトで Lodash のようなユーティリティライブラリを使用する場合は、 _.range()
代わりにLodashによって提供される関数。 次のコードスニペットは、 range()
定義したばかりの関数とLodashの関数:
range(1, 5); // returns [1, 2, 3, 4, 5]
_.range(1, 5); // returns [1, 2, 3, 4]
次に、 fetchPageNumbers()
のメソッド Pagination
クラス。 このメソッドは、ページネーションコントロールに表示されるページ番号を生成するためのコアロジックを処理します。 最初のページと最後のページを常に表示する必要があります。
まず、いくつかの変数を定義しました。 totalNumbers
コントロールに表示される合計ページ数を表します。 totalBlocks
表示されるページ番号の合計に、左右のページインジケータ用の2つの追加ブロックを加えたものを表します。
もしも totalPages
より大きいではありません totalBlocks
、から数値の範囲を返します 1
に totalPages
. それ以外の場合は、ページ番号の配列を次のように返します。 LEFT_PAGE
と RIGHT_PAGE
ページがそれぞれ左と右にこぼれるポイントで。
ただし、ページネーションコントロールにより、最初のページと最後のページが常に表示されるようになっていることに注意してください。 左右のページコントロールが内側に表示されます。
ここで、を追加します render()
ページネーションコントロールをレンダリングできるようにするメソッド。
の中に Pagination
クラス、後 constructor
と fetchPageNumbers
メソッド、以下を追加します render
方法:
class Pagination extends Component {
// ...
render() {
if (!this.totalRecords || this.totalPages === 1) return null;
const { currentPage } = this.state;
const pages = this.fetchPageNumbers();
return (
<Fragment>
<nav aria-label="Countries Pagination">
<ul className="pagination">
{ pages.map((page, index) => {
if (page === LEFT_PAGE) return (
<li key={index} className="page-item">
<a className="page-link" href="#" aria-label="Previous" onClick={this.handleMoveLeft}>
<span aria-hidden="true">«</span>
<span className="sr-only">Previous</span>
</a>
</li>
);
if (page === RIGHT_PAGE) return (
<li key={index} className="page-item">
<a className="page-link" href="#" aria-label="Next" onClick={this.handleMoveRight}>
<span aria-hidden="true">»</span>
<span className="sr-only">Next</span>
</a>
</li>
);
return (
<li key={index} className={`page-item${ currentPage === page ? ' active' : ''}`}>
<a className="page-link" href="#" onClick={ this.handleClick(page) }>{ page }</a>
</li>
);
}) }
</ul>
</nav>
</Fragment>
);
}
}
ここでは、ページ番号を生成します array
を呼び出すことによって fetchPageNumbers()
以前に作成したメソッド。 次に、を使用して各ページ番号をレンダリングします Array.prototype.map()
. クリックを処理するために、レンダリングされた各ページ番号にクリックイベントハンドラーを登録していることに注意してください。
また、次の場合、ページネーションコントロールはレンダリングされないことに注意してください。 totalRecords
小道具が正しく渡されませんでした Pagination
コンポーネントまたはのみが存在する場合 1
ページ。
最後に、イベントハンドラーメソッドを定義します。
の中に Pagination
クラス、後 constructor
と fetchPageNumbers
メソッドと render
メソッドには、以下を追加します。
class Pagination extends Component {
// ...
componentDidMount() {
this.gotoPage(1);
}
gotoPage = page => {
const { onPageChanged = f => f } = this.props;
const currentPage = Math.max(0, Math.min(page, this.totalPages));
const paginationData = {
currentPage,
totalPages: this.totalPages,
pageLimit: this.pageLimit,
totalRecords: this.totalRecords
};
this.setState({ currentPage }, () => onPageChanged(paginationData));
}
handleClick = page => evt => {
evt.preventDefault();
this.gotoPage(page);
}
handleMoveLeft = evt => {
evt.preventDefault();
this.gotoPage(this.state.currentPage - (this.pageNeighbours * 2) - 1);
}
handleMoveRight = evt => {
evt.preventDefault();
this.gotoPage(this.state.currentPage + (this.pageNeighbours * 2) + 1);
}
}
あなたは gotoPage()
状態を変更し、 currentPage
指定されたページに移動します。 それは page
引数の最小値は 1
総ページ数の最大値。 それは最終的に onPageChanged()
新しいページネーション状態を示すデータを使用して、小道具として渡された関数。
コンポーネントがマウントされたら、を呼び出して最初のページに移動します this.gotoPage(1)
に示すように componentDidMount()
ライフサイクル方式。
使用方法に注意してください (this.pageNeighbours * 2)
の handleMoveLeft()
と handleMoveRight()
現在のページ番号に基づいて、ページ番号をそれぞれ左と右にスライドします。
これは、左から右への動きの相互作用のデモです。
これで完了です Pagination
成分。 ユーザーは、このコンポーネントのナビゲーションコントロールを操作して、さまざまなページのフラグを表示できます。
ステップ4—構築 App
成分
今、あなたは CountryCard
と Pagination
コンポーネント、あなたはあなたの中でそれらを使用することができます App
成分。
を変更します App.js
のファイル src
ディレクトリ:
- nano src/App.js
の内容を置き換えます App.js
次のコード行を使用します。
import React, { Component } from 'react';
import Countries from 'countries-api';
import './App.css';
import Pagination from './components/Pagination';
import CountryCard from './components/CountryCard';
class App extends Component {
state = { allCountries: [], currentCountries: [], currentPage: null, totalPages: null }
componentDidMount() {
const { data: allCountries = [] } = Countries.findAll();
this.setState({ allCountries });
}
onPageChanged = data => {
const { allCountries } = this.state;
const { currentPage, totalPages, pageLimit } = data;
const offset = (currentPage - 1) * pageLimit;
const currentCountries = allCountries.slice(offset, offset + pageLimit);
this.setState({ currentPage, currentCountries, totalPages });
}
}
export default App;
ここで初期化します App
次の属性を持つコンポーネントの状態:
allCountries
-これは、アプリ内のすべての国の配列です。 空の配列に初期化されます([]
).currentCountries
-これは、現在アクティブなページに表示されるすべての国の配列です。 空の配列に初期化されます([]
).currentPage
-現在アクティブなページのページ番号。 に初期化null
.totalPages
-すべての国のレコードの合計ページ数。 に初期化null
.
次に、 componentDidMount()
ライフサイクル方式では、を使用してすべての世界の国をフェッチします countries-api
呼び出しによるパッケージ Countries.findAll()
. 次に、アプリの状態を更新し、設定します allCountries
すべての世界の国々を含むために。 パッケージの詳細については、countries-apiドキュメントを参照してください。
最後に、 onPageChanged()
メソッド。ページネーションコントロールから新しいページに移動するたびに呼び出されます。 このメソッドはに渡されます onPageChanged
の小道具 Pagination
成分。
この方法で注意を払う価値のある2つの行があります。 最初はこの行です:
const offset = (currentPage - 1) * pageLimit;
The offset
valueは、現在のページのレコードをフェッチするための開始インデックスを示します。 使用する (currentPage - 1)
オフセットがゼロベースであることを確認します。 たとえば、表示しているとしましょう 25
ページごとのレコード、および現在ページを表示しています 5
. そうして offset
になります ((5 - 1) * 25 = 100)
.
たとえば、データベースからオンデマンドでレコードをフェッチしている場合、これはオフセットの使用方法を示すサンプルSQLクエリです。
SELECT * FROM `countries` LIMIT 100, 25
データベースや外部ソースからレコードをフェッチしていないため、現在のページに表示される必要なレコードのチャンクを抽出する方法が必要です。
2番目はこの行です:
const currentCountries = allCountries.slice(offset, offset + pageLimit);
ここでは、 Array.prototype.slice()
必要なレコードのチャンクを抽出するメソッド allCountries
を渡すことによって offset
スライスの開始インデックスとして (offset + pageLimit)
スライスを終了する前のインデックスとして。
注:このチュートリアルでは、外部ソースからレコードをフェッチしていません。 実際のアプリケーションでは、おそらくデータベースまたはAPIからレコードをフェッチすることになります。 レコードをフェッチするためのロジックは、 onPageChanged()
の方法 App
成分。
架空のAPIエンドポイントがあるとしましょう /api/countries?page={current_page}&limit={page_limit}
. 次のスニペットは、 axiosHTTPパッケージを使用してAPIからオンデマンドで国を取得する方法を示しています。
onPageChanged = data => {
const { currentPage, totalPages, pageLimit } = data;
axios.get(`/api/countries?page=${currentPage}&limit=${pageLimit}`)
.then(response => {
const currentCountries = response.data.countries;
this.setState({ currentPage, currentCountries, totalPages });
});
}
今、あなたは仕上げることができます App
コンポーネントを追加して render()
方法。
の中に App
クラス、しかし後 componentDidMount
と onPageChanged
、以下を追加します render
方法:
class App extends Component {
// ... other methods here ...
render() {
const { allCountries, currentCountries, currentPage, totalPages } = this.state;
const totalCountries = allCountries.length;
if (totalCountries === 0) return null;
const headerClass = ['text-dark py-2 pr-4 m-0', currentPage ? 'border-gray border-right' : ''].join(' ').trim();
return (
<div className="container mb-5">
<div className="row d-flex flex-row py-5">
<div className="w-100 px-4 py-5 d-flex flex-row flex-wrap align-items-center justify-content-between">
<div className="d-flex flex-row align-items-center">
<h2 className={headerClass}>
<strong className="text-secondary">{totalCountries}</strong> Countries
</h2>
{ currentPage && (
<span className="current-page d-inline-block h-100 pl-4 text-secondary">
Page <span className="font-weight-bold">{ currentPage }</span> / <span className="font-weight-bold">{ totalPages }</span>
</span>
) }
</div>
<div className="d-flex flex-row py-4 align-items-center">
<Pagination totalRecords={totalCountries} pageLimit={18} pageNeighbours={1} onPageChanged={this.onPageChanged} />
</div>
</div>
{ currentCountries.map(country => <CountryCard key={country.cca3} country={country} />) }
</div>
</div>
);
}
}
の中に render()
メソッドでは、国の総数、現在のページ、ページの総数、 <Pagination>
コントロール、そして <CountryCard>
現在のページの国ごとに。
合格したことに注意してください onPageChanged()
以前に定義したメソッド onPageChanged
の小道具 <Pagination>
コントロール。 これは、ページの変更をキャプチャするために非常に重要です。 Pagination
成分。 あなたも表示しています 18
ページあたりの国。
この時点で、アプリは次のスクリーンショットのようになります。
あなたは今持っています App
複数を表示するコンポーネント CountryCard
コンポーネントと Pagination
コンテンツを個別のページに分割するコンポーネント。 次に、アプリケーションのスタイリングについて説明します。
ステップ5—カスタムスタイルを追加する
以前に作成したコンポーネントにいくつかのカスタムクラスを追加していることに気付いたかもしれません。 これらのクラスのスタイルルールをいくつか定義しましょう。 src/App.scss
ファイル。
- nano src/App.scss
The App.scss
ファイルは次のスニペットのようになります。
/* Declare some variables */
$base-color: #ced4da;
$light-background: lighten(desaturate($base-color, 50%), 12.5%);
.current-page {
font-size: 1.5rem;
vertical-align: middle;
}
.country-card-container {
height: 60px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.country-name {
font-size: 0.9rem;
}
.country-region {
font-size: 0.7rem;
}
.current-page,
.country-name,
.country-region {
line-height: 1;
}
// Override some Bootstrap pagination styles
ul.pagination {
margin-top: 0;
margin-bottom: 0;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
li.page-item.active {
a.page-link {
color: saturate(darken($base-color, 50%), 5%) !important;
background-color: saturate(lighten($base-color, 7.5%), 2.5%) !important;
border-color: $base-color !important;
}
}
a.page-link {
padding: 0.75rem 1rem;
min-width: 3.5rem;
text-align: center;
box-shadow: none !important;
border-color: $base-color !important;
color: saturate(darken($base-color, 30%), 10%);
font-weight: 900;
font-size: 1rem;
&:hover {
background-color: $light-background;
}
}
}
あなたの App.js
参照するファイル App.scss
それ以外の App.css
.
注:これについて詳しくは、 CreateReactAppドキュメントを参照してください。
- nano src/App.js
import React, { Component } from 'react';
import Countries from 'countries-api';
import './App.scss';
import Pagination from './components/Pagination';
import CountryCard from './components/CountryCard';
スタイルを追加すると、アプリは次のスクリーンショットのようになります。
これで、追加のカスタムスタイルを備えた完全なアプリケーションができました。 カスタムスタイルを使用して、Bootstrapなどのライブラリによって提供されるデフォルトのスタイルを変更および拡張できます。
結論
このチュートリアルでは、Reactアプリケーションでカスタムページネーションウィジェットを作成しました。 このチュートリアルでは、APIを呼び出したり、データベースバックエンドとやり取りしたりしていませんが、アプリケーションでそのようなやり取りが必要になる場合があります。 このチュートリアルで使用されているアプローチに制限されることはありません。アプリケーションの要件に合わせて、アプローチを拡張できます。
このチュートリアルの完全なソースコードについては、GitHubのbuild-react-pagination-demoリポジトリを確認してください。 また、CodeSandboxでこのチュートリアルのライブデモを入手することもできます。
Reactの詳細については、 React.js シリーズのコーディング方法をご覧になるか、Reactトピックページで演習やプログラミングプロジェクトを確認してください。