当尝试异步进行两个 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/>
</>
如果没有可重现的示例,很难说出为什么会发生这种情况。也许是因为仅在第二个 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
});
}, []);