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

React Native中Firebase数据未获取完成就执行计算函数问题求助

问题原因

核心bug和Firebase请求时序无关,出在React状态更新的异步特性上:你调用setNewProduct(myProduct)后立刻执行myData(),此时newProduct这个state还没完成更新,myData里读取到的newProduct是更新前的旧值(大概率是空数组),自然没法基于刚拉取的经纬度做距离计算。
另外原代码还有两个隐藏问题:

  • 直接修改state数组里的元素,属于状态直接篡改,容易触发页面不刷新、状态错乱
  • 未声明就直接给myNewProduct、mydistance赋值,会污染全局作用域引发未知bug
修复代码

直接把从Firestore拉取到的最新商品数组作为参数传入计算函数,完全跳过等待state更新的环节,从根源避免时序问题:

function fetchProducts() {
  const myProduct = [];
  db.collection("item")
    .orderBy("createdAt", "desc")
    .get()
    .then((snapshot) => {
      snapshot.docs.forEach((doc) => {
        const { createdAt, category, image, values, latitude, longitude } = doc.data();
        myProduct.push({
          createdAt,
          id: doc.id,
          latitude,
          longitude,
          category,
          image,
          values,
        });
      });
      setNewProduct(myProduct);
      // 直接传入最新的商品数组,不依赖state更新后的值
      myData(myProduct);
    });
}

const myData = (productList) => {
  GetCurrentLocation().then(() => {
    // 遍历生成带距离的新数组,不直接修改原对象
    const productWithDistance = productList.map((element) => {
      const distance = calcDistance(
        element.latitude,
        element.longitude,
        newLatitude,
        newLongitude
      );
      return {
        ...element,
        distance
      };
    });
    // 按距离排序后更新展示用的商品列表
    productWithDistance.sort((a, b) => a.distance - b.distance);
    setProduct(productWithDistance);
  });
};
补充说明
  • React的state更新是批量异步执行的,只要执行setXxx后下一行代码立刻读取xxx,拿到的一定是更新前的旧值。如果后续逻辑必须依赖更新后的state,除了上面直接传参的方案,也可以用useEffect监听对应state变化,在state更新完成后再触发后续逻辑。
  • 所有涉及state的修改都要遵循不可变原则,不要直接给state里的对象、数组属性赋值,优先用展开运算符、map/filter等返回新值的方法生成新的状态对象,避免隐性bug。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 23:27:35