useInfiniteQueryで無限スクロールを実装する(Next.js)

はじめに

皆様こんにちは。
AMDlab Webエンジニアの塚田です。

最近Next.jsを使い始めました。その中でuseInfiniteQueryというものが便利に
感じたので今回ご紹介したいと思います。

Next.js

Reactをベースに開発された、フロントエンドフレームワークです。

useInfiniteQuery

useInfiniteQueryとは TanStack Query から提供されているreactの機能の一つで、
「無限スクロール」を簡単に実装することができます。

機能としては以下の流れで無限スクロールを実現しています。

  1. useInfiniteQuery を呼び、最初のデータを受け取る
  2. getNextPageParam で次のデータを取得するためのパラメータを返却する
    ※今回の実装ではページ番号のみ返却するようにしています。
  3. hasNextPageというフラグで次のデータがあるか確認します。
  4. 3.がtrueの場合、fetchNextPage を呼び、次のデータを取得する

無限スクロールの実装

開発環境
macOS Venture 13.0.1
Next.js 14.2.3
mysql 8.0

Next.js のルーティングにはPage RouterApp Router がありますが
今回はApp Routerを選択しました。以下フォルダ構成です。

mysql についてはdockerを利用してコンテナ化しました。dockerのコンテナ化等については
公式サイトを参照ください。
今回使うテーブルは以下のものになります。


まずtest_tableテーブルからデータを取得するAPIを用意します。
next-js-sample/app/api/test-api の下にroute.tsを配置します。
以下のコードを記述します。


useInfiniteQueryを利用した無限スクロールを実装していきます。スクロールのUIとして
react-infinite-scrollerInfiniteScrollを利用します。このコンポーネントのpropsである
loadMore
fetchNextPage メソッドを設定します。また hasMore hasNextPage
フラグ
を設定します。

hasMore のhasNextPageがtrueの時 loadMoreで設定したfetchNextPageメソッドに
よりデータが取得され、スクロール内のデータが更新されます。
 他にもInfiniteScrollにはpropsがあるので調べてみてください。

以下useInfiniteQueryとInfiniteScrollを使用しているコンポーネントのコードです。

Next.jsのルーティングによりfetch の第1引数 api/test-api とすることで
next-js-sample/api/test-api/route.ts のGETメソッドが呼び出され、
test_tableテーブルからデータを取得することができます。

最後に初期表示のpage.tsxのコードです。

useInfiniteQuery(useQueryも)を使用する場合には上記のように
QueryClientQueryClientProviderを使用する必要があります。

※ルーティングにapp routerを選択している為、”use client” をつけないと
エラーとなるのでご注意ください。

実行結果

今回は100件ずつ取得しています。次のデータはLoading…が表示されたのち、
表示されます。

おわりに

Next.js(React)の無限スクロールの実装はかなり簡単に実装できることをご紹介させていただきました。
他にも便利な機能が満載のようなので勉強して業務等に活用していきたいと思います。

Tech
Javascript
ARTICLES