ReactでSWRを使ってAPIからデータを取得してみた

2023.03.23 13:56
2023.03.30 15:17
ReactでSWRを使ってAPIからデータを取得してみた

ReactでAPIからのデータ取得を試してみました。方法はいくつかあるようですが、今回はSWRというものを使ってみます。自分なりにやってみたもののメモなので、他にもいろいろとやり方はあるのだと思います。

※React18を使用しています。

1. インストール

まずはこの2つをインストールします。

yarn add swr
yarn add suspense

suspenseは、読み込むまでのローディング処理をやってくれるものみたいです。最近のものなので、古いReactだとうまく動かない場合があるようです。

2. 完成版

完成版はこんな感じになりました。

import List from "List";
import React, { Suspense } from "react";
import { Loading } from "Loading";

export const TagIndexPage: React.FC = () => {
  const setIsReady = {};

  return (
    <>
      <Suspense fallback={<Loading />}>
        <TagList />
      </Suspense>
    </>
  );
};

List.tsxでは念の為、SWRからのデータが無かった場合にエラーにならないように、「<></>」として何も表示しないようにしてみました。

import useSWR from "swr";
import fetcher from "fetcher";
import { ErrorFallback } from "ErrorFallback";

export default function TagList() {
  const { data } = useSWR("/api/list", fetcher, {
    suspense: true,
  });

  if (!data.error) {
    return (
      {data.tag?
      <ul>
          {data?.map((tag: any) => (
            <li key={tag.id}>{tag.name}</li>
          ))}
        </ul>
      :<></>}
    );
  } else {
    return <ErrorFallback message="データを取得できませんでした" />;
  }
}
const fetcher = async(key: string) => {
  return fetch(process.env.REACT_APP_API_ENDPOINT + key).then((res) =>
    res.json()
  );
};

export default fetcher;
export function Loading() {
  return (
    <div>
      Loading
    </div>
  )
}
import React from "react";

type Props = {
  message: string;
};

export const ErrorFallback = ({ message }: Props) => {
  return (
    <div>
      <h1>エラーが発生しました</h1>
      <p>{message}</p>
    </div>
  );
};

画面はこんな感じになりました。

リスト1
リスト2
リスト3
リスト4
リスト5

3. 基本構造と手順

構造と手順をメモしてみました。構造とこんな感じっぽいです。

・ ページ
・ 取得したデータをページに表示するコンポーネント
・ データを取得するfetcher
・ ローディング中に表示するコンポーネント
・ エラー時に表示するコンポーネント

手順はこんな感じ

1. fetcherを作る(APIからのデータ取得処理をするパーツ)
2. 取得したデータを表示するコンポーネントを作る
3. データが取得できなければErrorFallbackを表示
4. ページ内で2のコンポーネントをsuspenseで挟む

データ表示コンポーネントがfetcherを使ってデータを取得。取得できるまではsuspenseに設定しているローディングのコンポーネントを表示。きちんと取得できたらデータ表示コンポーネントに展開。できなければErrorFallbackコンポーネントに表示。それをsuspenseが検知して、ローディングを解除し、データをページに表示、という流れみたいですね。コード的には相当スッキリします。

今回は以上です!