【问题标题】:React Async Function wrapped in a UseEffect包裹在 UseEffect 中的 React 异步函数
【发布时间】:2020-10-07 14:50:50
【问题描述】:

我对异步函数的工作原理感到困惑。

console.log 返回错误,因为 data.rates 尚不存在。但我认为因为 useEffect 函数是异步的,所以它下面的任何东西都会在异步结束后调用。

function App() {
  const [data, setData] = useState();

  useEffect(() => {
    (async () => {
      const result = await axios.get(
        "https://open.exchangerate-api.com/v6/latest"
      );
      setData(result.data);
    })();
  }, []);

  console.log(data.rates); <-- Error data.rates does not exist
  return <div>{!data ? "Loading..." : "Hello"}</div>;
}

【问题讨论】:

  • 最初您的状态 data 未定义,因此您在记录时遇到错误。
  • 状态更新后,您应该会看到记录的正确值。

标签: javascript reactjs async-await


【解决方案1】:

您的假设实际上是正确的,这种情况下的 useEffect 将在组件被挂载时运行,这意味着 console.log 将被调用两次——第一次使用初始值(未定义),第二次是在完成请求后实际设置数据(setData)时,useEffect 执行了副作用。您通常会在数据陈旧时提供“加载”状态。

function App() {
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState();

  useEffect(() => {
    (async () => {
      setLoading(true);
      const result = await axios.get(
        "https://open.exchangerate-api.com/v6/latest"
      );
      setLoading(false);
      setData(result.data);
    })();
  }, []);

  if (loading) return <div>Fetching data...</div>

  return <div>Hello</div>;
}

【讨论】:

    【解决方案2】:

    我觉得没有一个答案能真正回答这个问题。

    useEffect 不会停止执行流程,无论您在传递给它的回调中做什么都没关系。所以console.log(data.rates) 被执行,然后一旦组件被挂载,传递给useEffect 的回调就会被执行。由于回调(setData(result.data))中的状态正在更改,这会触发重新渲染,这次您应该看到记录了正确的值而没有任何错误。

    【讨论】:

      【解决方案3】:

      尝试这样做(我已经创建了一种解决方法)

      function App() {
          const [data, setData] = useState();
      
          useEffect(()=>{
              const setObtainedData=async()=>{
                  const result = await axios.get("https://open.exchangerate-api.com/v6/latest");
                  setData(result.data);
              };
              setObtainedData();
          },[]);
      
          if(data){
              console.log(data.rates);
          }
          return <div>{!data ? "Loading..." : "Hello"}</div>;
      };
      

      【讨论】:

        猜你喜欢
        • 2020-08-08
        • 2019-11-12
        • 2020-09-02
        • 1970-01-01
        • 2020-01-20
        • 2013-08-23
        • 1970-01-01
        • 2021-04-23
        相关资源
        最近更新 更多