React Native中Firebase更新数组后页面不展示最新数据问题
问题原因
- 你使用普通全局数组存储Firebase返回的数据,不属于React的响应式状态,数组内容更新时React无法感知,不会触发组件重新渲染,因此页面不会更新。
- Firebase的
on('value')是异步监听,你导出的data初始为空数组,等异步回调拿到数据修改数组时,组件已经完成首次渲染,没有触发更新的逻辑。你看到的Expo保存代码后显示数据,是因为热重载触发了整个组件重新加载,才拿到了修改后的数组内容。
解决方法
将数据存储逻辑迁移到React组件内,配合useState存储响应式数据,useEffect注册和销毁Firebase监听,修改后的代码如下:
import React, { useState, useEffect } from 'react'; import {StyleSheet, Text, StatusBar, View, TouchableOpacity, ScrollView } from 'react-native'; import firebase from 'firebase'; import 'firebase/database'; export default function Index({navigation}) { // 用React响应式状态存储用户数据,状态变更会自动触发组件重渲染 const [userList, setUserList] = useState([]); useEffect(() => { // 注册Firebase实时数据监听 const userRef = firebase.database().ref().child('users'); const listener = userRef.on('value', (snapshot) => { const newData = []; if(snapshot.exists()){ snapshot.forEach((datasnapshot)=>{ newData.push({key: datasnapshot.key.toString()}) }) } else { newData.push({key: 'No one has written yet'}) } // 更新状态触发页面刷新 setUserList(newData); }); // 组件卸载时移除监听,避免内存泄漏 return () => userRef.off('value', listener); }, []); return ( <View style={styles.container}> <Text style={{color: '#000000', fontSize: 30, fontWeight: 'bold', marginTop: StatusBar.currentHeight}}>Index</Text> <ScrollView> {userList.map((item,key)=>{ if(item.key == "No one has written yet"){ return(<Text key={key} style={styles.item}>{item.key}</Text>) } else{ return( <TouchableOpacity key={key} onPress={()=>navigation.navigate('Details',item.key)}> <Text style={styles.item}>{item.key}</Text> </TouchableOpacity> ) } })} </ScrollView> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, item: { marginTop: 10, fontSize: 20, fontWeight: 'bold', color: '#000000', textAlign: 'center' } });
原来的getdata.js可以直接删除,不需要再导入使用。如果需要在多个组件共享这份用户数据,可以将监听逻辑封装到React Context中,避免重复注册监听,所有子组件都可以直接访问更新后的数据。
内容的提问来源于stack exchange,提问作者Varun V Gowda
相关产品推荐
相关产品推荐

