我正在使用Firebase Cloud Firestore制作任务应用程序
我添加了一个realtime listener
,以便使用新任务重新渲染Flatlist。
但是我遇到了一个问题,state tasks = []
被附加到old state
上,这导致平面列表中的任务重复。
我只想刷新整个列表。
这是我的实时侦听器代码:
this.state = {
tasks: [],
};
fetchTasks() {
try {
this.setState({loading: true});
const uid = auth().currentUser.uid;
const tempTasks = [];
firestore()
.collection('Tasks')
.where('uid', '==', `${uid}`)
.onSnapshot(snapshot => {
snapshot.forEach(doc => {
console.log('realtime: ', JSON.stringify(doc.data(), null, 2));
tempTasks.push({
taskId: doc.id,
data: doc.data(),
});
});
this.setState({tasks: []});
this.setState({tasks: tempTasks, loading: false});
console.log('tasks: ', this.state.tasks.length);
});
} catch (e) {
this.setState({loading: false});
Alert.alert('Error fetching tasks', `${e}`, [{text: 'OK'}]);
console.log('err in realtime', e);
}
}
render() {
return (
<FlatList
data={this.state.tasks}
renderItem={this._renderItem}
keyExtractor={(item, index) => index.toString()}
/>
)
最终:添加任务后,任务1的副本也会出现,因为在状态中附加了tasks = []
,而不是同时刷新任务1和任务2。
tempTasks的日志:
tempTasks [
{
"taskId": "FljhGGlsFN7yrD4GajDe",
"data": {
"status": "pending",
"createdOn": {
"_seconds": 1578761968,
"_nanoseconds": 66000000
},
"title": "Task 1",
"deadline": {
"_seconds": 1578761940,
"_nanoseconds": 0
},
"description": "apsdfplsdv",
"author": "yashGmail",
"uid": "t2kHrhIMbLggj2BpxKbJrPW9GL42"
}
},
{
"taskId": "GhF5nYalbTZZZH5j2lNO",
"data": {
"status": "pending",
"createdOn": {
"_seconds": 1578762188,
"_nanoseconds": 226000000
},
"title": "Task 2",
"deadline": {
"_seconds": 1578761940,
"_nanoseconds": 0
},
"description": "asdvlksdk",
"author": "yashGmail",
"uid": "t2kHrhIMbLggj2BpxKbJrPW9GL42"
}
}
]
非常感谢您的帮助。
答案 0 :(得分:2)
您需要检查事件.onSnapshot(snapshot => {})
是仅由较新的元素触发还是由所有元素触发。从您的代码中很明显,您正在用state.tasks
更新tempTasks
,因此非常清楚tempTasks
中的数据也是重复的,这就是我上面解释的原因。>
如果使用所有数据触发了onSnapshot
,则可以尝试以下操作:
firestore()
.collection('Tasks')
.where('uid', '==', `${uid}`)
.onSnapshot(snapshot => {
console.log(snapshot) // This to check what data is inside snapshot
const tempTasks = snapshot.map(doc => ({
taskId: doc.id,
data: doc.data(),
}))
this.setState({tasks: tempTasks, loading: false});
})