SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

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

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

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

  • X ポスト
  • このエントリーをはてなブックマークに追加

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

  • X ポスト
  • このエントリーをはてなブックマークに追加

対象読者

  • 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の役割は、あくまでも非同期処理の状態管理やキャッシュの管理です。

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
SWRを使ってみる

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
現場で役立つ! React向けライブラリ詳説連載記事一覧

もっと読む

この記事の著者

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

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

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

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

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/13836 2021/04/12 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング