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
相关产品推荐
相关产品推荐

