【问题标题】:previous state persisting even after calling setState() with new data即使在使用新数据调用 setState() 后,先前的状态仍然存在
【发布时间】:2025-12-02 00:15:01
【问题描述】:

我正在使用 Firebase Cloud Firestore 制作任务应用

我添加了一个 realtime listener 用于重新渲染平面列表,如果添加了任何新任务。

但我面临一个问题,即 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()}
      />
    )

最初:一项任务

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

临时任务日志:

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

非常感谢您的帮助。

【问题讨论】:

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


    【解决方案1】:

    您需要检查事件.onSnapshot(snapshot =&gt; {}) 是仅由较新的元素触发还是由所有元素触发。从您的代码中可以清楚地看出您正在用tempTasks 更新state.tasks,因此很明显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});
    })
    

    【讨论】:

    • 这适用于添加新任务,但是当删除任务并调用侦听器时,会从 state.tasks = [] 中删除错误的任务,例如,如果我删除任务 1,则任务 3 从state.tasks = []。虽然监听器查询结果是正确的,只是删除了Task 1。
    • 检查您的snapshot 参数。正如您所看到的,这里的逻辑非常简单,只需将您在快照中获取的数据添加到状态。因此,如果数据错误,则意味着您正在删除错误的数据或其他错误。
    最近更新 更多