3
0

More than 1 year has passed since last update.

ReactのカスタムフックでAPIから非同期で値を取得する

Last updated at Posted at 2022-12-12

はじめに

カスタムフックからAPIを呼び出す実装の際、つまずきポイントがいくつかあり大変だったので、忘れないように備忘録を残しましす。

前提条件

早速コード

useNews(カスタムフック)

import { useState, useEffect } from "react";
import { Article } from "../types";

export const useNews = (
  url: string
): {
  articles: Article[];
  isLoading: boolean;
} => {
  const [isLoading, setIsLoading] = useState<boolean>(true);
  const [articles, setArticles] = useState<Article[]>([]);

  useEffect(() => {
    const fetchNews = async () => {
      try {
        const res = await fetch(url);
        const data = await res.json();

        setArticles(data.hits);
        setIsLoading(false);
      } catch (error) {
        setIsLoading(false);
      }
    };
    fetchNews();
  }, [url]);

  return {
    articles: articles,
    isLoading: isLoading,
  };
};

(呼び出し側)
import { useNews } from "../api/getNews";

export default function En() {
  const url = `https://hn.algolia.com/api/v1/search?query=programing`;
  const { articles, isLoading } = useNews(url);
  if (isLoading) {
    return <div>ローディング中</div>;
  }
  return (
    <div>
        {/* articlesを使ったなにか */}
    </div>
  );
}

つまずきポイント1

APIをasync/awaitで呼び出したいけど、カスタムフックuseNewsは同期的に呼びたい

(呼び出し側)
// useNewsにasyncを使えない
const { articles, isLoading } = useNews(url);

カスタムフック内のuseEffectでasync/awaitを使う

useEffect(() => {
    // useEffect「内」でAPI取得関数を定義する
    const fetchNews = async () => {
      try {
        const res = await fetch(url);
        const data = await res.json();

        setArticles(data.hits);
        setIsLoading(false);
      } catch (error) {
        setIsLoading(false);
      }
    };
    // useEffect「内」でAPI取得関数を呼ぶ
    fetchNews();
  }, [url]);

つまずきポイント2

カスタムフックを更新できない

useEffectの配列に更新されるstateを入れる

useEffect(() => {
    // 略
  }, [url]);//urlが更新したらカスタムフックが走る

まとめ

カスタムフックを再試行したいときはuseEffectを使おう

参考

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0