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

React Native Hooks刷新页面调用数据异常及onSnapshot循环问题求解

问题根因

首次刷新无数据的原因

你最初版本监听ref的useEffect依赖项是空数组,只会在组件首次挂载时执行1次,此时getData还没完成AsyncStorage的异步读取,ref还是初始空值,所以onSnapshot监听器根本没有被注册。热更新时组件会保留之前的状态(ref已经有值),触发useEffect重新执行,所以能正常获取数据。

修改后日志循环触发的原因

你设置了每2秒执行一次的setInterval,每次调用setRef时传入的都是新生成的Firestore查询对象(引用地址每次都不一样),而监听ref的useEffect依赖了ref,每次ref变化都会先销毁旧的监听器再注册新的监听器,每次注册成功都会触发一次onSnapshot回调,就会不停打印日志,产生无意义的性能消耗。

修复方案

直接去掉完全多余的轮询定时器,onSnapshot本身就支持Firestore数据的实时推送更新,不需要手动轮询刷新查询引用:

const [getData, setGetData] = useState();
const [userBookingData, setUserBookingData] = useState([]);

const initializeData = async() => {
  const userToken = await AsyncStorage.getItem('user_id');
  setGetData(JSON.parse(userToken));
}

useEffect(() => {
  initializeData();
},[])

// 拿到用户数据后直接绑定监听器即可
useEffect(() => {
  if(!getData?.number) return;
  // 直接生成查询引用,不需要存到state里
  const ref = firestore().collection('**********').where("SendersNo", "==", getData.number);
  // 注册监听器,拿到销毁函数
  const unsubscribe = ref.onSnapshot(querySnapshot => {
    const list = [];
    querySnapshot.forEach(doc => {
        const {
            id,driverName,driverContactNumber,driverRating,driverPlateNumber,driverTrackingNumber,userPlaceName,
            destinationPlaceName,PaymentMethod,Fare
        } = doc.data();
        list.push({id: doc.id,driverName,driverContactNumber,driverRating,
          driverPlateNumber,driverTrackingNumber,userPlaceName,destinationPlaceName,PaymentMethod,Fare});
    });
    setUserBookingData(list);
    console.log("HEY!");
  });
  // 组件卸载/依赖变化时销毁监听器
  return () => unsubscribe();
},[getData])

const CurrentTransaction = () => {
  if(userBookingData.length === 0)
  {
    return (
      <View>
        <Text>You don't have a Current Transaction</Text>
      </View>
    )
  }
  else
  {
    return userBookingData.map((element) => {
      return (
        <View key={element.id}>
             <View>
                 <Text>{element.driverName}</Text>
                 {/* 其他字段按需求渲染即可 */}
             </View>
        </View>
         )
        });
     }
}

优化说明

  • 移除了冗余的ref状态和轮询定时器,避免不必要的重复监听器注册
  • 监听器直接依赖getData,只有用户标识变化时才会重新注册监听器,不会重复触发
  • onSnapshot本身会在Firestore后端数据变化时主动推送更新,完全满足自动刷新页面的需求
  • 补充了监听器的销毁逻辑,避免内存泄漏
  • 调整了空状态判断逻辑,直接用userBookingData的长度判断,避免出现ref存在但还没拿到数据的空白展示问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 16:12:00