You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS页面渲染前如何正确发起两个API请求?

React异步请求中状态更新延迟导致的API调用问题解决

问题描述

在React中发起两个异步API请求时,第二个API调用依赖第一个请求返回的player状态,但直接访问useState定义的player变量时,需要等待页面重新渲染才能拿到最新值,导致第二个请求无法正确获取参数。尝试过用isLoading控制加载状态,也试过多种Promise/异步方案(包括用setTimeout实现的非优化Promise),都没解决问题。

原代码实现

状态定义

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

原API调用代码

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);
        });
    })();
  }, []);

渲染代码

<>
  <Navbar/>
  {isLoading && <Spinner/>}
  {player && team && <Player/>}
  <LoginWidget/>
  <Footer/>
</>

问题原因

React的useState状态更新是异步且批量处理的,在同一个异步函数中调用setPlayer后,立刻访问player变量,拿到的仍然是该函数闭包中的旧值,无法获取刚更新的team_ID,导致第二个API请求参数错误。

修复方案

直接使用第一个API请求返回的响应数据(而非useState的player变量)作为第二个请求的参数,同时改用try-catch处理请求异常,并调整isLoading的设置逻辑,确保无论请求成功或失败都会结束加载状态。

修复后的代码

useEffect(() => {
    const fetchData = async () => {
      setIsLoading(true);
      try {
        const { data: playerRes } = await axios.get(
          `http://localhost:4242/player/${id}`
        );
        setPlayer({ ...playerRes });
        const { data: teamRes } = await axios.get(
          `http://localhost:4242/team/${playerRes.team_ID}`
        );
        setTeam({ ...teamRes });
      } catch (err) {
        console.log(err);
      }
      setIsLoading(false);
    };
    fetchData();
  }, []);

内容的提问来源于stack exchange,提问作者ConnorWitmer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 14:43:14