React Native导航返回时FlatList未同步更新最新数据问题
问题根因
你当前的实现存在两个核心问题导致返回列表页不更新:
- 数据库读取用的
once('value')方法只会在主动调用readFunction时执行一次单次拉取,不会自动同步数据变更 - React Navigation的
navigate跳转不会销毁栈内的旧列表页,返回时不会触发组件重新挂载,如果你只在组件首次加载的useEffect里调用readFunction,返回时根本不会重新执行数据拉取逻辑,页面自然保留旧的state缓存。
可落地解决方法
你可以根据自己的业务场景选下面任意一种方案:
方案1:监听页面聚焦事件,每次回到列表页主动拉取最新数据
这个方案改动最小,只需要加导航的聚焦监听钩子即可:
首先引入对应依赖:import { useFocusEffect } from '@react-navigation/native';替换原来仅在组件挂载时拉取数据的逻辑,改为页面每次获得焦点就重新读库:
useFocusEffect( React.useCallback(() => { readFunction(); }, [userID]) );不管是从录入页navigate返回、切tab切回、后台切回前台,只要页面处于聚焦状态就会重新拉取最新数据,拉取完成后
setchildData会自动触发FlatList重渲染,展示最新内容。方案2:替换单次读取为Firebase实时监听,数据变更自动同步
如果需要数据实时更新(比如多端操作、同页面其他入口改数据也能自动刷新),可以把once换成持续监听的on方法。注意:使用实时监听必须在useEffect的清理函数里移除监听,否则会造成内存泄漏,甚至出现页面卸载后仍然更新state导致的报错
参考实现代码:useEffect(() => { const dataRef = db.ref('childData/'+ userID); const handleDataUpdate = snapshot => { const childNameVal = []; snapshot.forEach((child) => { childNameVal.push({ nameVal: child.val()['childName'], idChild: child.val()['idChild'], }) }) setchildData(childNameVal) }; // 注册监听,路径下数据变更时自动执行更新逻辑 dataRef.on('value', handleDataUpdate); // 组件卸载时移除监听 return () => dataRef.off('value', handleDataUpdate); }, [userID])用这个方案的话,不需要等页面聚焦才拉数据,只要数据库对应路径内容有变化,前端会立刻收到更新,列表实时同步,不需要手动触发刷新。
方案3:页面间传刷新回调,录入成功后主动触发列表更新
如果不想每次聚焦页面都读库,可以在跳转到录入页的时候把列表刷新方法作为参数传递:// 列表页跳录入页的逻辑 navigation.navigate('AddDataPage', { refresh: () => readFunction() })在录入页完成数据提交、准备返回列表页时,调用传入的刷新方法:
// 录入页保存成功后的逻辑 const { refresh } = route.params; // 先触发列表刷新 refresh(); // 再返回列表页 navigation.goBack();这个方案只会在确实录入了新数据的时候触发一次刷新,性能开销最小。
内容的提问来源于stack exchange,提问作者MZainurroriziqin Akbar
相关产品推荐
相关产品推荐

