简体   繁体   English

反应显示加载 animation 用于 api 调用持续时间

[英]React display loading animation for api call duration

Currently I feel like the more I read about React, the less I understand.目前我觉得我对 React 的了解越多,我的理解就越少。

I am trying to solve this simple problem: During the data-fetching for my component, show a loading spinner.我正在尝试解决这个简单的问题:在为我的组件获取数据期间,显示一个加载微调器。

This is how I thought it would work:这就是我认为它会起作用的方式:

  1. use State to monitor loading使用 State 监控加载
    const [isLoading, setIsLoading] = useState(false);

  2. use conditional rendering on this state在此 state 上使用条件渲染
    return ({isLoading && <div>I am loading</div>});

  3. setLoading when api call is started and reset it when a reponse arrived当 api 调用开始时 setLoading 并在响应到达时重置它

    useEffect(() => { const fetchData = async () => { let result; setIsLoading(true); result = await api.get(URL); // this takes 2000ms. setData(result;data); setIsLoading(false); }; fetchData(), };[api]);

But, as the documentation says, setState is async and can be sent in batches.但是,正如文档所说, setState是异步的,可以分批发送。 the network call takes 2 seconds, but I never see a loading animation.网络调用需要 2 秒,但我从来没有看到加载 animation。
So how do I do this?那么我该怎么做呢?

Edit: This is how you can do this.编辑:这就是你可以做到这一点的方法。 My error was somewhere else - the setIsLoading(false) was also in a different useEffect , which had the data as dependency.我的错误在其他地方 - setIsLoading(false)也在不同的useEffect中,它具有数据作为依赖项。 I had to wrap the entire logic inside that useEffect with if(data) , since on the first render, my data was undefined, but this still triggered the initial useEffect , probably like the old componentDidMount logic I guess - and the loading anim stopped way too soon.我不得不用if(data)将整个逻辑包装在useEffect中,因为在第一次渲染时,我的数据是未定义的,但这仍然触发了最初的useEffect ,可能就像我猜的旧 componentDidMount 逻辑一样 - 并且加载动画停止方式太快了。

I think what you've got there works.我认为你有什么工作。 I've implemented it here: codesandbox我在这里实现了它: codesandbox

import "./styles.css";
import React, { useState, useEffect } from "react";

export default function App() {
  const [isLoading, setIsLoading] = useState(false);
  useEffect(() => {
    const fetchData = async () => {
      let result;
      setIsLoading(true);
      result = await api.get(URL); // this takes 2000ms!
      //setData(result.data);
      setIsLoading(false);
    };

    fetchData();
  }, []);
  return (
    <div className="App">
      {isLoading ? <p>currently loading</p> : null}
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

const api = {
  get: async function () {
    await new Promise((r, e) => setTimeout(r, 2000));
  }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM