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

React useState loading状态不更新求助:请求数据时loading始终为false

问题分析与解决方案

嘿,作为Hooks新手遇到这个问题太正常啦!我一眼就瞅出问题所在了——你异步函数的执行顺序搞反了。

问题根源

你在useEffect里调用完fetchData()之后,立刻就执行了setIsLoading(false)。但fetchData是异步函数,里面的await axios(...)会暂停函数执行,等待请求返回结果。这时候外面的代码可不会等它,直接就把isLoading设回false了。相当于isLoading刚被设为true,瞬间又被改成false,所以你console里看到的始终是false。

修正后的代码

把setIsLoading(false)放到异步请求完成的逻辑里,而且一定要加上错误处理,避免请求失败时loading一直卡在true状态:

const Pokedex = () => { 
  const [data, setData] = useState({}); 
  const [isLoading, setIsLoading] = useState(false); 
  const pokemonId = 1; 

  useEffect(() => { 
    const fetchData = async () => { 
      try {
        setIsLoading(true); // 发起请求前开启loading
        const result = await axios( 
          `https://pokeapi.co/api/v2/pokemon/${pokemonId}` 
        ); 
        setData(result.data); // 请求成功后更新数据
      } catch (error) {
        // 可选:添加错误提示逻辑,比如弹出提示框或者记录日志
        console.error('获取宝可梦数据失败:', error);
      } finally {
        setIsLoading(false); // 不管成功还是失败,最后都关闭loading
      }
    }; 
    fetchData(); 
  }, [pokemonId]); 

  console.log("loading: ", isLoading);

  // 渲染逻辑示例:根据loading状态切换显示内容
  return (
    <div className="pokedex">
      {isLoading ? (
        <div className="loading">加载中...</div>
      ) : (
        <div className="pokemon-info">
          <h2>{data.name}</h2>
          <p>身高: {data.height / 10}m</p>
        </div>
      )}
    </div>
  );
};

新手友好提示

  • 异步函数内部的代码会按顺序等待,但外部代码不会等待异步函数执行完毕,所以结束loading的逻辑必须放在异步函数内部。
  • 用try/catch/finally包裹异步请求是好习惯:try里放正常请求逻辑,catch处理请求失败的情况,finally里放不管成功失败都要执行的逻辑(比如关闭loading)。
  • Hooks的状态更新本身是异步的,但这次的问题和状态更新异步无关,主要是异步函数的执行顺序问题哦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 19:52:50