SWR

エスダブリューアール

SWR を分かりやすく

今回の課題は「SWR」ですね。こっちはちょっと新しめのツールで、最初は「え、これ何?」って感じかもしれないですよね。でもご安心を。実はこれ、かなり便利で、使いこなせればWeb開発がグッと楽になるんですよ。めっちゃ便利なんですよ!

SWRは、Next.jsを開発したVercel社から出てるライブラリで、主にデータフェッチのために使われます。名前の由来はHTTPのキャッシュ不整合問題を表す原則である「Stale-While-Revalidate」から来ています。

例え話を使うと、SWRはまるで新鮮なパンを提供するパン屋さんのようなもの。お客さん(ユーザー)がパン(データ)を求めると、すぐに手元にあるパン(キャッシュデータ)を出します。それと同時に、厨房で新たにパン(新しいデータ)を焼き始める。パンが焼き上がれば、それをすぐにお客さんに提供します。つまり、新鮮なパンを提供しつつ、待ち時間も最小限に抑えるんです。

同じように、SWRはキャッシュを利用して速やかにデータを表示し、バックグラウンドで新しいデータを取得して更新します。「そもそもこれ使う意味あるん?」って方いるかと思いますが、データを素早く表示しつつ、常に最新の状態を保てるので、ユーザー体験を向上させるのに一役買ってくれるんです。

さらに、SWRはリトライやページネーションなどの機能も提供しているので、これ一つでデータフェッチに関する複雑な問題を一手に解決できるんですよ。ここまで大丈夫ですか?これがSWRの凄さなんですよ。だいぶヤバいやつですよね〜(褒め言葉)。

結論

SWR(Stale While Revalidate)は、React Hooksベースのデータフェッチングライブラリで、HTTPリクエストを効率的に取り扱うためのものです。その名前は、HTTPキャッシュの無効化戦略から取られています。"Stale While Revalidate"とは、キャッシュが古くなっても新たなデータが取得できるまで古いデータを使用し続けるという意味です。

SWR を使うメリット

SWRには、以下のような特徴があり、これらがその利用メリットとなります。

リアルタイムでのデータ同期

SWRは、データの変更を自動的に検出し、UIをリアルタイムで更新します。データが変更された場合、SWRはすぐに新しいデータに更新します。

キャッシュと再検証

SWRは、データフェッチを行うたびに結果をキャッシュし、次回以降の同じリクエストではキャッシュからデータを取得します。また、バックグラウンドで新しいデータの取得を試み、必要な場合にはキャッシュを更新します。

エラーハンドリングとリトライ

SWRは、エラーハンドリングとリトライ機能を備えています。リクエストが失敗した場合、自動的にリトライを行います。

スクロール位置の保持

データの更新時にページのスクロール位置が変わらないため、ユーザー体験が向上します。

SWR を実装

では、Next.jsとTypeScriptを用いたSWRの実装例を見てみましょう。

まず、SWRを使用するためには、プロジェクトにSWRライブラリをインストールする必要があります。以下のコマンドでインストールできます。

npm install swr

次に、データフェッチ関数を作成します。この例では、JSONPlaceholderから投稿データを取得する関数を作成します。

import axios from 'axios';

const fetcher = async (url: string) => {
  const response = await axios.get(url);
  return response.data;
};

このfetcher関数は、SWRによって使用され、指定したURLからデータを取得します。

次に、SWRフックを使用してデータをフェッチし、そのデータを表示するReactコンポーネントを作成します。

import useSWR from 'swr';
import { fetcher } from './fetcher';

type Post = {
  id: number;
  title: string;
  body: string;
};

const Posts = () => {
  const { data, error } = useSWR<Post[]>('/posts', fetcher);

  if (error) return <div>Failed to load posts</div>;
  if (!data) return <div>Loading...</div>;

  return (
    <ul>
      {data.map((post) => (
        <li key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.body}</p>
        </li>
      ))}
    </ul>
  );
};

このコンポーネントでは、useSWRフックを使用して/postsエンドポイントからデータを取得しています。エラーが発生した場合やデータがまだ読み込まれていない場合の表示も考慮しています。

さらに、データが更新された場合に再フェッチを行うためのボタンを追加しましょう。

import useSWR from 'swr';
import { fetcher } from './fetcher';

type Post = {
  id: number;
  title: string;
  body: string;
};

const Posts = () => {
  const { data, error, mutate } = useSWR<Post[]>('/posts', fetcher);

  if (error) return <div>Failed to load posts</div>;
  if (!data) return <div>Loading...</div>;

  return (
    <div>
      <button onClick={() => mutate()}>Refresh posts</button>
      <ul>
        {data.map((post) => (
          <li key={post.id}>
            <h2>{post.title}</h2>
            <p>{post.body}</p>
          </li>
        ))}
      </ul>
    </div>
  );
};

ここでは、SWRフックからmutate関数を取得し、ボタンのonClickハンドラーで呼び出しています。これにより、ボタンをクリックするとデータが再フェッチされます。

以上がNext.jsとTypeScriptを使用したSWRの簡単な使い方です。このように、SWRを使用すると効率的なデータフェッチングとキャッシュ管理を行うことができ、リアルタイムなデータ同期やエラーハンドリングといった機能を手軽に利用することが可能です。