CodeZine(コードジン)

特集ページ一覧

React Hooks向けライブラリSWRとは? 通信とキャッシュ管理を簡便に

現場で役立つ! React向けライブラリ詳説 第3回

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2021/04/12 11:00

 Reactを使ってアプリケーション開発をしていく上で、JavaScriptによる通信の取り回しのよさや、通信結果のキャッシュをどう管理していくかは、重要な関心ごとです。今回は、通信とキャッシュ管理に特化したReact Hooks向けライブラリである「SWR」について解説します。

目次

対象読者

  • JavaScriptとWeb開発の基礎に理解がある方
  • Reactを用いたJavaScriptアプリケーション開発の経験者

前提環境

 筆者の検証環境は以下の通りです。

  • macOS Big Sur 11.2.1
  • Node.js 15.8.0/npm 7.5.0
  • React 17.0.1
  • react-scripts 4.0.2
  • SWR 0.4.2

React Hooksで通信結果をキャッシュする

 アプリケーション開発において、外部システムとのIO処理はパフォーマンスのボトルネックになりがちです。特に、ネットワークを介した通信はその最たるものでしょう。これを解決するための手法の一つとして、キャッシュ機構を利用する方法があります。ブラウザにも、HTTPヘッダー経由でサーバーと協調しながらキャッシュの有効期間を設定する手段が用意されていますね。サーバーやブラウザ側でキャッシュを制御してくれるのもありがたいのですが、もう少し細やかな制御をしたくなる場合もあります。

 例えば、シングルページアプリケーションのメモリが有効な間だけキャッシュが継続していて画面遷移を高速に行うことができ、ブラウザを再起動したらキャッシュが消える、といったライフサイクルにしたい場合は、アプリケーション側でキャッシュを制御したいところです。

 Reactの場合、簡単な通信の制御とキャッシュであれば、React HooksのuseStateuseEffectを利用して実装できます。アプリケーションの最上位のコンポーネントで通信結果を保持する方法を見てみましょう(リスト1)。

[リスト1]簡単な通信とキャッシュ
function App() {
  const [user, setUser] = useState(null); // (2)
  const [doRefetch, setDoRefetch] = useState(false); // (1)

  useEffect(() => {
    // レンダリング後にdoRefetchがtrueだったら通信する
    if (doRefetch) {
      fetch('/api/user')
        .then(res => res.json())
        .then(data => {
          setDoRefetch(false);
          setUser(data); // 読み込みが完了したらデータをセットする
        });
    }
  }, [doRefetch]);

  if (user === null) {
    // データがまだない場合は読み込み中のUIを表示する
    return <Loading />;
  }

  return (
    <div>
      <Header user={user} />
      <Content user={user} />
    </div>
  );
}

 キャッシュを更新したくなったら(1)で定義した関数でsetDoRefetch(true)を実行すればOKです。これで、ブラウザがページをリロードするまでは、(2)に保持したユーザー情報が維持されます。

 リスト1は参考実装でしたが、実用する場合は次のような課題を解決する必要がありそうです。

  • 通信先のエンドポイントが増えると実装量が大幅に増えるので簡素にしたい
  • キャッシュの更新タイミングを適切に制御したい
  • 任意のコンポーネント階層で手軽に通信結果を受け取りたい
  • 通信エラーをハンドリングしたい

 こういった課題を解決できるカスタムフックを自前で実装するのは、なかなか骨が折れそうです。

SWRとは

 SWRはデータ取得時の非同期処理の管理とキャッシュ管理を行うための、React Hooks向けライブラリです。

図1:SWR
図1:SWR

 SWRという名前は、RFC 5861で提唱された、HTTPキャッシュを破棄する方針の一つであるstale-while-revalidateに由来しています。stale-while-revalidateの方針でデータ取得を行う場合、まずは既存のキャッシュを返して、そのすぐ後にバックグラウンドで通信を行って、既存のキャッシュと取得したデータに違いがないかを検証します(この処理はrevalidate=再検証と呼ばれています)。キャッシュを利用して可能な限り素早くレスポンスを返すことと、可能な限りキャッシュを新しい状態に保つことを両立した方針と言えるでしょう。

 ライブラリとしてのSWRは、このstale-while-revalidateの方針による通信をより簡便に利用するために作られました。インターフェースはuseSWRというカスタムフックのみです。リスト1の通信処理をuseSWRを用いた形に書き直すと、リスト2の通りになります。

[リスト2]SWRを利用した通信処理のサンプル
import useSWR from 'swr';

const fetcher = (...args) => fetch(...args).then(res => res.json()); // (2)

function App() {
  const { data, error } = useSWR('/api/user', fetcher); // (1)

  if (data === null) {
    // データがまだない場合は読み込み中のUIを表示する
    return <Loading />;
  }

  return (
    <div>
      <Header user={data} />
      <Content user={data} />
    </div>
  );
}

 非同期処理や通信結果の保持に関する処理が(1)にまとまって、見通しがよくなりました。最終的な通信処理には(2)で設定してあるようにfetch関数を使っているので、通信方法自体に魔法があるわけではありません。SWRの役割は、あくまでも非同期処理の状態管理やキャッシュの管理です。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

あなたにオススメ

著者プロフィール

  • WINGSプロジェクト 中川幸哉(ナカガワユキヤ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XM...

バックナンバー

連載:現場で役立つ! React向けライブラリ詳説
All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5