Ваша проблема связана с вашей componentDidMount()
функцией и использованием onSnapshot()
. Каждый раз, когда происходит обновление вашей коллекции, все слушатели, прикрепленные с onSnapshot()
, будут срабатывать. В своем слушателе вы добавляете каждый документ в моментальном снимке в существующий список. Хотя этот список начинается пусто, к каждому последующему изменению к списку добавляются все документы в коллекции (включая старые, а не только изменения).
Существует два способа обработкимоментальный снимок слушателя, когда он входит - либо очищайте существующий список и создавайте его заново при каждом изменении, либо обрабатывайте только изменения (новые записи, удаленные записи и т. д.).
В качестве примечания: при использовании onSnapshot()
Рекомендуется сохранить возвращаемую функцию «отписаться» (например, this.stopChangeListener = this.db.onSnapshot(...)
). Это позволит вам позже заморозить состояние вашего списка без получения дальнейших обновлений с сервера, позвонив по номеру someGym.stopChangeListener()
.
Метод воссоздания
Для простоты я бы рекомендовал использовать этометод, если вы не имеете дело с большим количеством предметов.
componentDidMount() {
this.stopChangeListener = this.db.onSnapshot((snapshot) => {
var postsArray = snapshot.docs.map((doc) => {
return {
id: doc.id,
// title: doc.data().title,
body: doc.data().body
});
});
this.currentPosts = postsArray;
this.setState({
posts: postsArray
});
});
};
Метод повторных изменений
Этот метод зависит от условий гонки и открывает возможностьдесинхронизация с базой данных, если обрабатывается неправильно.
componentDidMount() {
this.stopChangeListener = this.db.onSnapshot((snapshot) => {
var postsArray = this.currentPosts.clone() // take a copy to work with.
snapshot.docChanges().forEach((change) => {
var doc = change.document;
var data = {
id: doc.id,
// title: doc.data().title,
body: doc.data().body
});
switch(change.type) {
case 'added':
// add new entry
postsArray.push(data)
break;
case 'removed':
// delete potential existing entry
var pos = postsArray.findIndex(entry => entry.id == data.id);
if (pos != -1) {
postsArray.splice(pos, 1)
}
break;
case 'modified':
// update potential existing entry
var pos = postsArray.findIndex(entry => entry.id == data.id);
if (pos != -1) {
postsArray.splice(pos, 1, data)
} else {
postsArray.push(data)
}
}
});
this.currentPosts = postsArray; // commit the changes to the copy
this.setState({
posts: postsArray
});
});
};
В качестве примечания: я бы также рассмотрел возможность перемещения
this.currentPosts = ...
в функцию
this.setState()
.