0Pricing
React Academy · レッスン

useInfiniteQueryによる無限スクロールとページネーション

ページ単位のデータを取得し、useInfiniteQueryで次のページをシームレスに読み込みます。

「useInfiniteQueryによる無限スクロールとページネーション」はCoddyKit上の無料React Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはReact Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 React Academyコースには全4レッスンが含まれています。

ようこそ

このレッスンでは、useInfiniteQuery を使ってページ分割されたデータを取得し、ユーザーのスクロールに応じて追加のページを読み込む無限スクロールパターンを実装します。

useInfiniteQuery とは

useInfiniteQuery はデータを「pages」単位で取得します。各ページは個別に取得され、キャッシュされた一覧に追加されます。fetchNextPage、hasNextPage、isFetchingNextPage などのユーティリティを提供します。

基本設定

initialPageParam と getNextPageParam を定義します。queryFn は現在の pageParam を受け取り、結果の1ページ分を返す必要があります。
const { data, fetchNextPage, hasNextPage } = useInfiniteQuery({
  queryKey: ['posts'],
  queryFn: ({ pageParam }) =>
    fetch('/api/posts?cursor=' + pageParam).then(r => r.json()),
  initialPageParam: 0,
  getNextPageParam: (lastPage) => lastPage.nextCursor ?? undefined,
});

getNextPageParam

getNextPageParam は、最後に取得したページとすべてのページを受け取ります。次のページのカーソルまたは番号を返し、これ以上ページがないことを示すには undefined または null を返します(hasNextPage が false に設定されます)。
getNextPageParam: (lastPage, allPages) => {
  return lastPage.hasMore ? lastPage.nextCursor : undefined;
}

すべてのページのレンダリング

data.pages はページごとの結果を格納した配列です。これらをフラット化して、すべての項目を連続したリストとしてレンダリングします。
const allPosts = data.pages.flatMap(page => page.items);

return (
  <ul>
    {allPosts.map(post => <li key={post.id}>{post.title}</li>)}
  </ul>
);

追加読み込みボタン

fetchNextPage を呼び出す「Load More」ボタンを追加します。これ以上ページがない場合や取得処理中は、ボタンを無効にします。
<button
  onClick={() => fetchNextPage()}
  disabled={!hasNextPage || isFetchingNextPage}
>
  {isFetchingNextPage ? 'Loading...' : hasNextPage ? 'Load More' : 'No more posts'}
</button>

IntersectionObserver による無限スクロール

リストの末尾にある sentinel 用の div に IntersectionObserver を設定します。それがビューポートに入ったら、fetchNextPage を自動的に呼び出します。
const observerRef = useRef();
useEffect(() => {
  const observer = new IntersectionObserver(entries => {
    if (entries[0].isIntersecting && hasNextPage) fetchNextPage();
  });
  if (observerRef.current) observer.observe(observerRef.current);
  return () => observer.disconnect();
}, [hasNextPage, fetchNextPage]);

<div ref={observerRef} />  {/* sentinel at bottom */}

双方向無限スクロール

チャットアプリでは、両方向へのスクロールに対応します。過去のメッセージには fetchNextPage を使用し、新しいメッセージには getPreviousPageParam と fetchPreviousPage を使用します。

ページ方式とカーソル方式のページネーション

オフセット方式またはページ方式では、initialPageParam=1 とし、getNextPageParam は lastPage.page + 1 を返します。カーソル方式では、最後の項目の ID をカーソルとして使用します。ライブデータには、カーソル方式のほうが安定しています。
// Offset-based
getNextPageParam: (lastPage) => lastPage.page + 1

無限クエリの再フェッチ

無限クエリに対して invalidateQueries を呼び出すと、最初のページだけが再フェッチされます。すべてのページを再フェッチするには(新しい投稿が追加された後など)、queryClient.resetQueries または refetchType: 'all' を使用します。

理解度チェック

これ以上読み込むページがないことを示すには、getNextPageParam は何を返す必要がありますか?

まとめ

useInfiniteQuery は data.pages にページを蓄積します。flatMap でフラット化してレンダリングします。停止するには getNextPageParam が undefined を返すようにします。ボタンのクリックや IntersectionObserver をトリガーにして fetchNextPage を呼び出すと、無限スクロールを実現できます。

コース完了

おめでとうございます。**React Query: Server State Management** を修了しました。これで TanStack Query を使って、データの取得、キャッシュ、変更、ページネーション、無限スクロールができるようになりました。

よくある質問

「useInfiniteQueryによる無限スクロールとページネーション」レッスンは無料ですか?

はい。「useInfiniteQueryによる無限スクロールとページネーション」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、React Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 React Academyコースには全4レッスンが含まれています。

「useInfiniteQueryによる無限スクロールとページネーション」で何を学びますか?

ページ単位のデータを取得し、useInfiniteQueryで次のページをシームレスに読み込みます。 ブラウザで直接実行するハンズオンコードでReact Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

React Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのReact Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「useInfiniteQueryによる無限スクロールとページネーション」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このReact Academyレッスンでコードを書いて実行できますか?

はい。すべてのReact Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. React QueryとQueryClientのセットアップ
  2. キャッシュ、Stale Time、バックグラウンド再取得
  3. useMutationによるMutation
  4. useInfiniteQueryによる無限スクロールとページネーション
← React Academyに戻る