📚

Suspenseコンポーネント, SWRライブラリを利用したAPIデータ取得

2022/06/28に公開

はじめに

  • Suspenseコンポーネントを利用し、SWRライブラリ経由でデータ取得、その取得結果をコンポーネントへ表示。まずは基本動作。
  • SWRライブラリはVercel社作成ライブラリで、詳細は他の記事が詳しい。
  • Suspenseタグ内部のコンポーネントのローディングが完了していない場合、propsのfallbackの内容を表示する。
    • Suspenseタグ内部のコンポーネントは複数指定が可能。API1, API2, API3を呼び出すコンポーネントを内部に指定し、すべてのデータ取得が完了するまで、fallbackの内容が表示される。
  • useQueryの返り値isLoadingにより出力を変える書き方等より、シンプルで可読性のある記載が可能となる。
SWRライブラリによるARI呼び出し ./src/components/hooks/useAllUsersSWR.ts(カスタムフック)
  • useSWR
    • 1番目引数(key): APIを指定、ここではJSONPlaceholderのUsersAPI呼び出し。
    • 2番目引数(fetcher): データをフェッチし、Promiseを返す関数を指定。
      • 非同期処理 asyncの戻り値の型はPromiseであるべきだが、実際の戻り値はJSONに変換することは可能。The fetcher here is an async function that accepts the key of SWR, and returns the data.
    • 3番目引数(option): オプション指定。この部分に{ suspense: true }を指定する。
  • useSWRで取得するデータの戻り値の型を指定。
import useSWR from "swr";

import { User } from "../types/User";

export const useAllUsersSWR = () => {
  const fetcher = async (url: string): Promise<any> => {
    const resonse = await fetch(url);
    return resonse.json();
  };

  const { data, error } = useSWR<Array<User>>(
    "https://jsonplaceholder.typicode.com/users",
    fetcher,
    { suspense: true }
  );
  return { data, error };
};
出力表示するコンポーネント ./src/components/Pages/FetchCheck.tsx
import { FC, memo, Suspense, useCallback } from "react";
import { useNavigate } from "react-router-dom";
import { useAllUsersSWR } from "../../hooks/useAllUsersSWR";

const ResultComponent = () => {
  const { data } = useAllUsersSWR();

  return (
    <>
      <div>
        <p>Fetch Users is below</p>
        {data.map((user) => (
          <div key={user.id}>{user.name}</div>
        ))}
      </div>
    </>
  );
};

export const FetchCheck: FC = memo(() => {
  const navigate = useNavigate();
  const onClickHome = useCallback(() => {
    navigate("/");
  }, [navigate]);

  return (
    <>
      <div>
        <Suspense fallback={<p>厄介な広告ページの表示</p>}>
          <ResultComponent />
        </Suspense>
        <button onClick={onClickHome}>to home</button>
      </div>
    </>
  );
});
APIレスポンスの型指定 ./src/types/Users.ts
export type Users = {
  id: number;
  name: string;
  username: string;
  email: string;
  address: {
    street: string;
    suite: string;
    city: string;
    zipcode: string;
    geo: {
      lat: string;
      lng: string;
    };
  };
  phone: string;
  website: string;
  company: {
    name: string;
    catchPhrase: string;
    bs: string;
  };
};
Repository

https://github.com/hiroharu8864/react-swr-fetch

Discussion