🍉

∞ SWRで爆速な無限ローディングを実装する完全ガイド

に公開

こんにちは、今回はReact界隈で非常によく使われているデータフェッチライブラリ SWR を使って、"無限スクロール・無限ローディング" をスマートに実装する方法を解説します。

1. そもそもSWRとは?

SWRは Vercel 社が開発した、React向けの"データフェッチ管理ライブラリ"です。キャッシュ管理やリトライ、フォーカスリフェッチなどがほぼ自動で行われ、コード量を最小化しながら堅牢なデータ取得が可能になります。

公式: https://swr.vercel.app/

特徴:
✅キャッシュ & リフェッチ戦略(Stale-While-Revalidate)
✅ローディング・エラーハンドリングが簡単
✅型安全なフェッチも容易(TypeScript対応)
✅useSWRInfinite を使えば無限スクロールが爆速実装できる

2. useSWRInfiniteを使って無限ローディングを作る

基本形

import useSWRInfinite from 'swr/infinite';
const PAGE_SIZE = 20;

const getKey = (pageIndex: number, previousPageData: any) => {
  if (previousPageData && previousPageData.length === 0) return null; //   // ページングが最後に到達したかどうかの判定
  return `/api/items?page=${pageIndex}&limit=${PAGE_SIZE}`;
};

const { data, size, setSize, isLoading, error } = useSWRInfinite(getKey, fetcher);

ポイント:
🎯 getKey 関数は ページごとのAPIエンドポイントを生成する。
✅ previousPageData.length === 0 の場合、次のリクエストを止める(データがもうない)
✅ setSize(size + 1) を呼べば次ページをロードできる。

これだけで基本の無限スクロールが完成します!

3. パフォーマンス爆上げTips:Parallel Fetching Mode

SWR v2.1.0から parallelオプション が追加されました。これで、ページごとのリクエストを順番待ちせず同時に並列発行できるようになりました。

const { data, size, setSize, isLoading, error } = useSWRInfinite(getKey, fetcher, {
  parallel: true,
});

✅ 効果が大きい場面:

  • 各ページのデータ依存がない(独立している)場合
  • リスト系、一覧画面などで一気にデータを読みたいとき

4. 実戦で使えるオプションまとめ

よりリッチな無限スクロール体験を作るために、以下のオプションも併用すると良いです。

1. revalidateFirstPage: false

無限スクロール中に最初のページまでリフェッチされるとUXが悪くなります。

revalidateFirstPage: false

2. persistSize: true

ページ数(size)をコンポーネントの再マウント後も保持します。

persistSize: true

3. fallbackData

最初からキャッシュやプリフェッチしておいたデータを使えます

fallbackData: initialData

5. 無限スクロール実装例(Intersection Observer)

最後に、画面の下にスクロールしたら自動ロードする実装例も紹介します!

import { useEffect, useRef } from 'react';

const LoadMore = () => {
  const { data, size, setSize, isLoading } = useHogehoge();
  const loadMoreRef = useRef<HTMLDivElement>(null);
  useEffect(() => {
    if (!loadMoreRef.current) return;
    const observer = new IntersectionObserver((entries) => {
      if (entries[0].isIntersecting) {
        setSize((s) => s + 1);
      }
    });
    observer.observe(loadMoreRef.current);
    return () => observer.disconnect();
  }, [loadMoreRef, setSize]);

  return <div ref={loadMoreRef}>{isLoading && 'Loading...'}</div>;
};

これだけで、超スムーズな無限ローディングができます!

🎯 まとめ

✅ SWRのuseSWRInfiniteは無限スクロール実装に最適
✅ parallel: trueを使うと劇的にフェッチ速度が改善する
✅ revalidateFirstPageやpersistSizeでさらにUX向上
✅ IntersectionObserverを組み合わせて完璧な無限ロード体験を!

ぜひプロダクトに取り入れてみてください!✨

Discussion