反应useEffect钩子和Async / await自己的获取数据功能?

时间:2019-03-05 17:06:14

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

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

我使用 useState useEffect 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

我不确定在哪里在哪里 呼叫 fetchData 功能的地方。我在useEffect里面做吗?正确的地点?而且,此呼叫只会发生一次?因为我使用 []

通常,您会怎么做?

2 个答案:

答案 0 :(得分:1)

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

我相信您可以从fetchData函数的解耦中受益,并使其更加通用,例如:

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

  return json;
};

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

  useEffect(() => {
    const { disclaimer } = fetchData("https://api.coindesk.com/v1/bpi/currentprice.json");

    setState(disclaimer)
  }, []);

  return <div>{data}</div>;
};

答案 1 :(得分:0)

另一种选择是使用自调用功能:

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