この記事の最終更新日: 2025年4月30日
はじめに
フロントエンドで API からデータを取得するとき、useEffect
と fetch
を組み合わせた「お決まりのコード」を書くのにうんざりした経験はありませんか?Vercel が開発する SWR(Stale‑While‑Revalidate) は、その煩雑さを一気に解消してくれる React Hooks ライブラリです。本記事では、SWR の基本概念から使い方のコツ、よくある疑問までを初心者にもわかりやすく解説します。

想定読者
- React で API 通信を扱っているエンジニア
- useSWR の導入を検討している方
- React Query との違いを知りたい方
1. SWR とは?
SWR は HTTP キャッシュの戦略 Stale‑While‑Revalidate(「古いデータを使いながら裏で最新を取得する」)にちなんで名付けられました。ざっくり言えば「手元のキャッシュをすぐ表示し、その裏で最新データを取得してキャッシュを更新する」ふるまいをライブラリレベルで実現してくれます。
1‑1. なぜ SWR が必要?
- 即時表示:キャッシュがあればローディングスピナーを極力減らせる(UX 向上)
- 自動再検証:バックグラウンドで最新データを取得して UI を更新
- コード量の削減:
useEffect
・axios
・状態管理のセットアップが不要で簡潔なコードに
2. インストールと最小構成
npm install swr
# または
yarn add swr
最小限のコードはわずか 4 行です。
import useSWR from 'swr'
const fetcher = (url: string) => fetch(url).then(res => res.json())
const { data, error, isLoading } = useSWR('/api/users', fetcher)
- fetcher:データ取得ロジックを関数として渡す。HTTP リクエストを行い、JSON を返す。
- キー:キャッシュを識別するユニークな文字列(ここでは
/api/users
) - data / error / isLoading:状態管理を SWR が自動的に行ってくれる
3. 核心概念(用語の解説)
用語 | 意味・役割 | ポイント |
---|---|---|
key | キャッシュ ID | 同じ key を使うとデータは共有される |
fetcher | データ取得関数 | 非同期で Promise を返せば OK(axios でも fetch でも可) |
mutate | キャッシュの手動更新関数 | UI を即座に変更したいときに使う(例:フォーム送信直後など) |
revalidate | データの再取得を明示的に行う関数 | mutate(key) と似た動きだが、戻り値が不要なときに便利 |
フォールバック | 初期値を渡す仕組み | SSR(サーバーサイドレンダリング)で使うと初回の読み込みが高速になる |
3‑1. ステートマシンの流れ
- キャッシュがあるか確認(キーに紐づいたデータがあるか)
- キャッシュがあれば即表示+裏で fetcher を実行
- 新しいデータが取得できたら、キャッシュと画面の内容を更新
4. よく使うオプションの補足解説
useSWR(key, fetcher, {
refreshInterval: 5000, // 5秒ごとに自動で再フェッチ(ポーリング)
revalidateOnFocus: false, // タブを切り替えた時に再フェッチしない
suspense: true, // React の Suspense を使ってローディング制御
})
- refreshInterval:一定間隔で自動的に最新データを取得。リアルタイムな UI に。
- revalidateOnFocus:タブ復帰時のネットワーク通信を防ぐ。モバイルでの通信量削減に。
- suspense:React 18 以降で導入された UI 待機の仕組み。ローディング表示を統一管理。
5. 実践サンプル:ページネーション付き一覧
ページを切り替えると API から新しいデータを取得します。その際に keepPreviousData
を使うことで、データの「チラつき」を防ぐことができます。
function UsersList() {
const [page, setPage] = useState(1)
const { data, isLoading } = useSWR(`/api/users?page=${page}`, fetcher, {
keepPreviousData: true,
})
if (isLoading) return <p>読み込み中...</p>
return (
<>
<ul>{data.users.map(u => <li key={u.id}>{u.name}</li>)}</ul>
<button onClick={() => setPage(p => p + 1)}>次へ</button>
</>
)
}
6. React Query との違い(初心者向け比較)
比較項目 | SWR | React Query |
---|---|---|
バンドルサイズ | 軽量(~4KB) | やや重め(~36KB) |
提供する機能 | データ取得とキャッシュに特化 | ミューテーションやキャッシュ制御など多機能 |
学習コスト | 低め | やや高め(設定項目が多い) |
適した場面 | 単純な取得が多い小〜中規模アプリ | 状態遷移が多い中〜大規模アプリ |
7. ベストプラクティス集(初心者が守りたいポイント)
- fetcher を共通化する:API 通信処理をまとめることで、保守性が向上します。
- データ整形は fetcher の中で行う:コンポーネント側をシンプルに保てます。
- エラーバウンダリを使う:ネットワークエラーなどの例外で UI が崩れないように。
- mutate を使った即時 UI 更新:POST 直後など、最新状態をすぐに画面へ反映。
- TypeScript を使う:戻り値の型定義で、コード補完やバグ防止に効果的。
8. SSR/ISR での使い方(Next.js)
Next.js ではサーバーサイドで先にデータを取得し、クライアントに渡す fallback
を活用できます。
export async function getServerSideProps() {
const data = await fetcher('https://api.example.com/users')
return { props: { fallback: { '/api/users': data } } }
}
function Page({ fallback }) {
return (
<SWRConfig value={{ fallback }}>
<UsersList />
</SWRConfig>
)
}
9. まとめ
SWR は React アプリのデータ取得を劇的にシンプル&高速化するライブラリです。キャッシュ戦略やローディング処理を手軽に実装できるため、学習コストに対して得られるメリットが大きいのが魅力です。この記事で紹介した基本やベストプラクティスを参考に、ぜひプロジェクトに導入してみてください。
10. 2024〜2025 アップデートハイライト
SWR は 2024 年末から 2025 年春にかけて v2.3 系へ進化し、以下のような改良が行われています。
バージョン | 日付 | 主な変更点 |
---|---|---|
2.3.3 | 2025‑03‑06 | useFocusRevalidatedAt 初期化修正 (#2857) と Prototype ポリュート回避 (#4099) |
2.3.2 | 2025‑02‑05 | keepPreviousData が undefined を返すバグを修正 (#4087) |
2.3.1 | 2025‑02‑05 | Mutation Hook の throwOnError オプション追加 (#3054) / Deno 環境検知の改善 (#4064) |
2.3.0 | 2024‑12‑23 | Promise を fallbackData として扱える (#2891) / React 19 互換 (#3047) / Suspense 関連バグ修正 (#3045) |
10.1 React 19 対応状況
v2.3.0
で peerDependencies が更新され React 19 が正式サポートされましたが、Concurrent Features の edge ケースについては issue #3051 で継続的に検証が進んでいます。
10.2 npm 最新版
2025 年 4 月時点で npm に公開されている最新安定版は v2.3.3 です(週間ダウンロード 130 万超)。ホスティングしているプロジェクトは npm info swr version
で確認すると良いでしょう。
10.3 移行のポイント
- 2.2 系からは 型定義の厳格化 により一部 generics の推論が変わるため、
as const
や型アサーションを見直す - React 19 を使う場合は
react
とreact-dom
を 19 系へ上げ、suspense: true
まわりのロジックを再点検 fallbackData
に Promise を渡す場合、古いコードで意図しない Suspense 発火がないか要確認
10.4 参考リソース
- v2.3.x リリースノート(GitHub Releases)
- SWR v2 ブログ
- npm バージョン履歴
- React 19 対応 issue/PR
参考リンク

大阪のエンジニアが書いているブログ。
コメント