【React.js + useSWR】SWR Infiniteを使ったページネーション・無限スクロールの実装方法を解説!
SWRは、Next.jsの開発元でもあるVercelが開発したReact向けのデータ取得ライブラリです。SWRは、アプリケーションのパフォーマンスを向上させ、データの取得と更新を簡単に行えるように設計されています。
ローカル上のキャッシュとサーバーとの間でデータを自動的に管理することで、適切なタイミングでキャッシュを更新します。また、オプションを設定することで、キャッシュの有効期限や再取得のタイミングを調整することができます。
今回は、そのSWRのうちページネーションを可能にするuseSWRInfinite
について解説します!
3行で要約すると
- SWRは、効率的なデータ取得とユーザー体験の向上を目指して設計されている。
useSWRInfinite
はSWRライブラリのフックで、ページネーションや無限スクロールを簡単に実装できる。- ボタンクリックやスクロールイベントを利用して、次のページのデータを動的に読み込む方法を提供する。
useSWRInfiniteとは?
useSWRInfinite
は、ページネーションや無限ローディングを実現するためのReactフックです。このフックを使用することで、ユーザーがスクロールするたびに新しいコンテンツを動的に読み込むことができます。これにより、従来のページネーションのように、ページ番号をクリックして新しいページを読み込む必要がなくなります。
useSWRInfinite
を使用することで、これらの問題を簡単に解決し、効果的な無限ローディングの実装を行うことができます。
セットアップ
useSWRInfinite
を使用するためのセットアップは非常に簡単です。まず、必要なライブラリをインストールします。
npm install swr
次に、あなたのReactコンポーネントでuseSWRInfinite
をインポートします。
import useSWRInfinite from 'swr'
これで、useSWRInfinite
を使用してページネーションや無限ローディングを実装する準備が整いました。このフックは、APIエンドポイントやデータの取得方法を指定することで、必要なデータを動的に取得することができます。
例えば、以下のコードは、/api/data
エンドポイントからデータを取得し、ページネーションを実装する方法を示しています。
const { data, error, size, setSize } = useSWRInfinite(
(index) => `/api/data?page=${index + 1}`,
fetcher
);
ここで、index
は現在のページ番号を示し、fetcher
はデータを取得するための関数です。size
は現在のページ数を示し、setSize
はページ数を更新するための関数です。
このように、useSWRInfinite
を使用することで、簡単にページネーションや無限ローディングの機能を追加することができます。
了解しました。
useSWRInfiniteの基本的な使い方
useSWRInfinite
を使用してデータのページネーションを実装する基本的な方法を以下に示します。
まず、必要な関数とフックをインポートします。
import useSWRInfinite from 'swr';
次に、getKey
関数とfetcher
関数を定義します。
const getKey = (pageIndex, previousPageData) => {
if (previousPageData && !previousPageData.length) return null; // reached the end
return `/api/data?page=${pageIndex + 1}`;
}
const fetcher = url => fetch(url).then(res => res.json());
これで、useSWRInfinite
フックを使用してデータを取得することができます。
function MyComponent() {
const { data, error, size, setSize } = useSWRInfinite(getKey, fetcher);
if (error) return <div>Error loading data</div>;
if (!data) return <div>Loading...</div>;
return (
<div>
{data.map((pageData, index) => (
<div key={index}>
{pageData.map(item => (
<div key={item.id}>{item.name}</div>
))}
</div>
))}
<button onClick={() => setSize(size + 1)}>Load more</button>
</div>
);
}
上記のコードでは、useSWRInfinite
を使用して複数ページのデータを取得し、それを表示しています。また、"Load more"ボタンをクリックすることで、次のページのデータを読み込むことができます。
引数
getKey この関数は、ページのインデックスや他の情報を受け取り、APIエンドポイントのURLを返します。
const getKey = (pageIndex, previousPageData) => {
if (previousPageData && !previousPageData.length) return null; // reached the end
return `/api/data?page=${pageIndex + 1}`;
}
fetcher
APIエンドポイントからデータを取得するための関数です。通常、fetch
やaxios
などのHTTPクライアントを使用して実装されます。
const fetcher = url => fetch(url).then(res => res.json());
返り値
data フェッチされたデータの配列。各ページのデータを含む配列の配列として返されます。
const { data } = useSWRInfinite(getKey, fetcher);
error データの取得中にエラーが発生した場合に返されるエラーオブジェクト。
const { error } = useSWRInfinite(getKey, fetcher);
if (error) console.error("Error fetching data:", error);
size 現在のページ数を示す数値。
const { size } = useSWRInfinite(getKey, fetcher);
console.log("Current page size:", size);
setSize ページ数を更新するための関数。次のページのデータを取得するために使用します。
const { setSize } = useSWRInfinite(getKey, fetcher);
const loadMore = () => setSize(size + 1);
isValidating データの再検証が行われているかどうかを示すブール値。
const { isValidating } = useSWRInfinite(getKey, fetcher);
if (isValidating) console.log("Data is revalidating");
mutate データを手動で再検証するための関数。
const { mutate } = useSWRInfinite(getKey, fetcher);
const refreshData = () => mutate();
これらの引数と返り値を組み合わせることで、ページネーションや無限スクロールのロジックを簡単に実装することができます。
ボタンを押して次のページを読み取る実装
useSWRInfinite
を使用して、ボタンをクリックすることで次のページのデータを読み込む方法を以下に示します。
まず、useSWRInfinite
フックを使用してデータを取得します。
const { data, size, setSize } = useSWRInfinite(getKey, fetcher);
次に、"次のページを読み込む"ボタンを実装します。このボタンは、クリックされるとsetSize
関数を使用してページ数を増やし、次のページのデータを読み込みます。
<button onClick={() => setSize(size + 1)}>次のページを読み込む</button>
このボタンのクリックイベントは、現在のページ数(size
)に1を加えて、setSize
関数を呼び出すことで次のページのデータを取得します。
また、すべてのデータが読み込まれた場合やエラーが発生した場合には、ボタンを非活性にするなどの処理を追加することができます。
無限スクロールの実装
無限スクロールは、ユーザーがページの最後までスクロールすると自動的に次のページのデータを読み込む機能を指します。useSWRInfinite
を使用することで、この機能を簡単に実装することができます。
まず、useSWRInfinite
フックと必要な関数をセットアップします。
const { data, size, setSize } = useSWRInfinite(getKey, fetcher);
次に、スクロールイベントを監視して、ユーザーがページの最後までスクロールしたかどうかを判断します。これを実現するために、window
オブジェクトのscroll
イベントを使用します。
useEffect(() => {
const handleScroll = () => {
if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
setSize(size + 1);
}
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, [size, setSize]);
これらのシンプルな実装を使用して、ユーザーがボタンをクリックすることで次のページのデータを動的に読み込む機能を追加することができます。
まとめ
今回の記事では、useSWRInfinite
の基本的な使い方から、ボタンをクリックして次のページを読み込む方法、無限スクロールの実装方法までを詳しく解説しました。これらの知識を活用することで、ユーザー体験を向上させるデータ取得のロジックを簡単に実装することができます。