在reactJS中渲染我的页面之前如何正确地进行两个API调用?

问题描述 投票:0回答:1

当尝试异步进行两个 API 调用时,第二个 API 调用的

useState()
不会在页面上更新,直到页面重新呈现。我试图在使用
isLoading
渲染之前检查页面是否正在加载。

我尝试了几种不同的承诺/异步方法 - 甚至使用

setTimeout()

创建我自己的未优化版本的承诺

isLoading

  const [isLoading, setIsLoading] = useState(false);

Api Calls

useEffect(() => {
    setIsLoading(true);
    (async () => {
      await axios.get(`http://localhost:4242/player/${id}`).then((res) => {
        const data = res.data;
        setPlayer({ ...data });
      });
      await axios
        .get(`http://localhost:4242/team/${player.team_ID}`)
        .then((res) => {
          const data = res.data;
          setTeam({ ...data });
          setIsLoading(false);
        });
    })();
  }, []);

Render

<>
  <Navbar/>
  {isLoading && <Spinner/>}
  {player && team && <Player/>}
  <LoginWidget/>
  <Footer/>
</>
javascript reactjs asynchronous
1个回答
0
投票

如果没有可重现的示例,很难说出为什么会发生这种情况。也许是因为仅在第二个 API 调用完成后才将

isLoading
设置为
false
,这可能无法与 React 组件的初始渲染(或重新渲染)很好地同步。

无论哪种方式,由于两个 API 调用并不相互依赖,因此最好使用

Promise.all
同时触发它们,然后仅在两者都完成后才继续。

我就是这样做的:

useEffect(() => {
  setIsLoading(true);
  Promise.all([
    axios.get(`http://localhost:4242/player/${id}`),
    axios.get(`http://localhost:4242/team/${player.team_ID}`)
  ])
  .then(([playerRes, teamRes]) => {
    setPlayer({ ...playerRes.data });
    setTeam({ ...teamRes.data });
    setIsLoading(false);
  })
  .catch(error => {
    // handle errors
  });
}, []);
© www.soinside.com 2019 - 2024. All rights reserved.