【问题标题】:React useEffect hook and Async/await own fetch data func?React useEffect hook 和 Async/await 自己的获取数据函数?
【发布时间】:2019-07-27 05:33:15
【问题描述】:

我尝试创建一个从服务器获取数据的函数,它可以工作。 但我不确定这是否正确?

我创建了一个函数组件来获取数据,使用 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

我不确定是 where 调用 fetchData 函数的地方。我在useEffect里面做那个?正确的地点?而且,这个电话只会发生一次?因为我使用[]

一般来说,你会怎么做这样的事情?

【问题讨论】:

  • 您的代码看起来不错。是的,您在 useEffect 中执行此操作。是的,它只发生一次,因为您使用了[ ]
  • 好的,正确的地方是下面的函数调用她?
  • 是的,由于空数组,调用只会在组件安装时发生。第二个参数中的数组为钩子提供了观察变化的内容,并且只有在这些依赖项中的任何一个发生变化时才会应用效果。传入一个空告诉钩子你的组件不依赖于道具/状态,因此只会在组件挂载上应用钩子。

标签: javascript reactjs asynchronous async-await react-hooks


【解决方案1】:

总的来说,您正朝着正确的方向前进。对于获取数据,您需要使用 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>;
};

【讨论】:

  • 在本例中,您需要等待 fetchData 调用或执行 .then。除非我错过了什么?
  • 另外,我不明白这是如何工作的,因为您不能在 async 函数之外使用 await,可以吗?所以await fetchData 无效。
  • 我是 hooks 新手,但您不需要使用 setData(disclaimer) 代替 setState(disclaimer) 吗?
【解决方案2】:

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

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));
  });
}

【讨论】:

    猜你喜欢
    • 2020-02-02
    • 2020-01-06
    • 2023-03-14
    • 2021-02-14
    • 2020-01-07
    • 1970-01-01
    • 1970-01-01
    • 2021-08-06
    • 1970-01-01
    相关资源
    最近更新 更多