web-dev-qa-db-ja.com

React useEffectフックと非同期/独自のフェッチデータ関数の待機?

サーバーからデータを取得する関数を作成してみましたが、うまくいきました。しかし、それが正しい方法かどうかはわかりませんか?

seStateseEffectおよびAsync/Awaitを使用して、データをフェッチする関数コンポーネントを作成しました。

import React, { useState, useEffect } from "react";

const Fetch = () => {
  const [data, setData] = useState(null);
  useEffect(() => {
    const fetchData = async () => {
      let res = await fetch(
        "https://api.coindesk.com/v1/bpi/currentprice.json" //example and simple data
      );
      let response = await res.json();
      setData(response.disclaimer); // parse json
      console.log(response);
    };
    fetchData();
  }, []);
  return <div>{data}</div>;
};

export default Fetch; // don't run code snippet, not working, this component must be imported in main

whereからcallfetchData関数の場所がどこにあるかわかりません。私はそれをuseEffect内で行いますか?適切な場所?そして、この呼び出しは1つだけ発生しますか? []を使用しているため

一般的に、あなたはこのようなことをどのように行いますか?

3
Milosh N.

全体として、あなたは正しい方向に向かっています。データを取得するには、useEffectを使用し、2番目の引数として[]を渡して、最初のマウント時にのみ起動するようにします。

私はあなたがfetchJson関数を分離し、それをより一般的にすることから利益を得ることができると信じています:

const fetchJson = async (url) => {
  const response = await fetch(url);
  return response.json();
};

const Fetch = () => {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetchJson("https://api.coindesk.com/v1/bpi/currentprice.json")
      .then(({ disclaimer }) => setData(disclaimer));
  }, []);

  return <div>{data}</div>;
};
3
Pavel Ye

別のオプションは、自己呼び出し関数を使用することです。

const Fetch = () => {
  const [data, setData] = useState(null);
  useEffect(() => {
    (async () => {
      let res = await fetch(
        "https://api.coindesk.com/v1/bpi/currentprice.json" //example and simple data
      );
      let response = await res.json();
      setData(response);
    })();
  }, []);
  return <div>{data}</div>;
};

フェッチロジックを別の関数に分離するという提案は良いアイデアであり、次のように実行できます。

const Fetch = () => {
  const [data, setData] = useState(null);
  useEffect(() => {
    (async () => {
      let response= await fetchData("https://api.coindesk.com/v1/bpi/currentprice.json");
      setData(response);
    })();
  }, []);
  return <div>{data}</div>;
};

const fetchData = async (url) => {
  const response = await fetch(url);
  const json = await response.json();

  return json;
};

さらに別のオプションは、useEffectの周りに次のような非同期関数をトリガーするラッパー関数を作成することです。

export function useAsyncEffect(effect: () => Promise<any>) {
  useEffect(() => {
    effect().catch(e => console.warn("useAsyncEffect error", e));
  });
}
1