即使使用新数据调用setState()之后,先前状态仍然存在

时间:2020-01-11 17:05:12

标签: reactjs firebase react-native google-cloud-firestore

我正在使用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()}
      />
    )

最初:一项任务 enter image description here

最终:添加任务后,任务1的副本也会出现,因为在状态中附加了tasks = [],而不是同时刷新任务1和任务2。

enter image description here

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"
    }
  }
]

非常感谢您的帮助。

1 个答案:

答案 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});
})