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

React Native useState计数器无法正常累加 无法触发setLoading问题

问题根因与修复方案

核心问题

  • 闭包陷阱:useEffect依赖数组为空,仅在组件挂载时执行一次,作用域内捕获的loopCount永远是初始值'1',每次setLoopCount(loopCount+1)都是基于同一个初始值计算,无法正常累加。只有组件刷新后effect重新执行才会拿到最新的state值,这就是仅按CTRL+S刷新时计数器才会自增1的原因。
  • 类型错误:loopCount初始值为字符串类型'1',执行+1操作时会触发字符串拼接(得到'11'而非数字2),和数字类型的data.length比对逻辑完全失效。
  • state异步更新:调用setLoopCount后立即读取loopCount拿到的还是更新前的旧值,if(loopCount >= data.length)的判断逻辑完全无效。
  • 异步操作无等待:AsyncStorage.getItem是异步方法,forEach不会等待回调执行就会跑完所有循环,此时大部分异步操作还未返回,loopCount还未完成累加,判断加载结束的时机完全错误。

修复后代码

// 初始值改为数字类型,从0开始计数
const [loopCount, setLoopCount] = useState(0);
const [isLoading, setLoading] = useState(true);

// 监听loopCount变化,达到阈值时关闭loading
useEffect(() => {
  if(loopCount >= data.length){
    setLoading(false);
  }
}, [loopCount, data.length])

useEffect(() => {
    const getPackages = async () => {
       try {
         const offerings = await Purchases.getOfferings();
         if (offerings.current !== null) {  
           // 收集所有异步操作
           const promises = [];
           data.forEach((category, index) => {
            if(category.entitlement_id){
                // 异步操作加入队列
                const promise = AsyncStorage.getItem(category.entitlement_id).then((value) => {
                  // 函数式更新,基于上一次state值计算,规避闭包问题
                  setLoopCount(prev => prev + 1);
                });
                promises.push(promise);
            }else{
              setLoopCount(prev => prev + 1);
            }
         })
         // 等待所有异步操作执行完成
         await Promise.all(promises);
       }else{
        console.log("No offerings found");
        setLoading(false);
       }
    } catch (e) {
      console.log("Error => " + e);
      // 异常场景关闭loading,避免无限加载
      setLoading(false);
    }
  }

  getPackages();
}, [])

补充说明

如果不需要用loopCount做其他渲染逻辑,可直接删除该state,在await Promise.all(promises)执行完成后直接调用setLoading(false)即可,代码更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 01:39:04