React Native FlatList使用extraData时重复渲染数据求助
解决Firebase数据更新时FlatList重复渲染旧数据的问题
嘿,我一眼就看出问题出在哪了——你每次Firebase触发value事件时,都在往同一个thisArr数组里塞数据,完全没清空旧内容!
问题核心
Firebase的value事件每次触发都会返回当前节点下的完整数据快照,不是增量更新的新数据。你之前的代码每次都把快照里的所有数据追加到同一个数组,导致数组里积累了多轮的旧数据,FlatList自然会重复显示。
修复步骤
每次回调都创建新数组
不要再复用外部的thisArr,每次进入value回调时,都新建一个数组来存储当前快照的所有数据:firebase.database().ref(`/thisThat/${uid}/arguments/this/`) .orderByChild('timestamp') .on('value', (snapshot) => { // 新建空数组,避免旧数据残留 const newThisArr = []; snapshot.forEach((child) => { newThisArr.push(child.val()); }); this.setState({ thisArguments: newThisArr }); });这样每次更新都会用全新的、排序后的数组替换state里的旧数据,FlatList就只会显示最新的完整数据了。
优化
keyExtractor避免渲染异常
你现在用index作为keyExtractor的返回值,当数组元素顺序变化(比如排序更新)或有新增删除时,React可能会错误复用旧组件,导致奇怪的渲染问题。建议用数据里的唯一标识作为key,比如Firebase自动生成的节点key:// 如果你的数据里存了Firebase的key(推荐在添加数据时就存入) keyExtractor={(item) => item.id} // 或者直接从快照的child.key获取(如果没存在数据里) // 这时候需要修改回调里的代码,把key也放进数组元素: snapshot.forEach((child) => { newThisArr.push({ ...child.val(), id: child.key // 把Firebase节点的key作为唯一ID }); });关于排序的说明
你用orderByChild('timestamp')的方式是完全正确的,Firebase会在服务端帮你完成排序,snapshot.forEach遍历的顺序就是排序后的顺序,所以不需要额外做客户端排序,只要保证每次用新数组存储即可。
这样修改后,FlatList就能正常渲染最新的排序后数据,不会再出现旧数据重复的问题啦!
内容的提问来源于stack exchange,提问作者Zander
相关产品推荐
相关产品推荐

