React useEffect hook 和 Async/await 自己的获取数据函数?

Mil*_* N. 5 javascript asynchronous async-await reactjs react-hooks

我尝试创建一个从服务器获取数据的函数,并且它有效。但我不确定这是否正确?

我使用useStateuseEffectAsync/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
Run Code Online (Sandbox Code Playgroud)

不确定调用fetchData函数的地方。我在 useEffect 中这样做吗?正确的位置?而且,这个调用只会发生一次?因为我使用[]

一般来说,你会如何做这样的事情?

Pav*_* Ye 8

总的来说,您正朝着正确的方向前进。为了获取数据,您需要使用useEffect[]作为第二个参数传递以确保它仅在初始安装时触发。

我相信您可以从解耦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>;
};
Run Code Online (Sandbox Code Playgroud)


Thu*_*kwa 5

另一种选择是使用自调用函数:

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>;
};
Run Code Online (Sandbox Code Playgroud)

将 fetch 逻辑分离到一个单独的函数的建议是一个好主意,可以按如下方式完成:

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;
};
Run Code Online (Sandbox Code Playgroud)

还有一种选择是围绕 useEffect 创建一个包装函数,它会为您触发异步函数,类似于:

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