Состояние реакции откатывается к предыдущему значению

#reactjs #firebase #google-cloud-firestore

# #reactjs #firebase #google-облако-firestore

Вопрос:

У меня проблема, которую я не мог понять. У меня есть эта функция, которая вычисляет общую цену:

 const [totalPrice, setTotalPrice] = useState(0);

const calcTotalPrice = (itemss) => {
  var sum = null;

  itemss.forEach(function (item) {
    sum  = item?.Quantity * item?.Prijs;
  });

  setTotalPrice(sum);
  console.log(totalPrice);
};
 

Это отлично работает, но когда я обновляю количество продукта, состояние не обновляется. Ну, это происходит, но затем возвращается к предыдущему значению. Вот результат, который я получаю:

 570
443
467
 

Что очень странно. Верхнее значение — это новое значение, второе — старое, и я не знаю, откуда берется третье. Функция вызывается каждый раз, когда вызывается функция GetItems():

 async function getItems() {
  setLoading(true);
  db.collection(`rooms/${roomId}/Items`).onSnapshot((querySnapshot) => {
    const itemss = [];
    querySnapshot.forEach((doc) => {
      itemss.push(doc.data());
    });
    setItems(itemss);
    calcTotalPrice(itemss);
    setLoading(false);
  });
}

useEffect(() => {
  getItems();
}, []);
 

Я не понимаю, что я здесь делаю неправильно. Любая помощь будет высоко оценена.

Комментарии:

1.Что, если вы totalPrice правильно зарегистрируете свое значение в отдельном useEffect с totalPrice как зависимость, чтобы оно регистрировалось после setTotalPrice(sum) обработки? useEffect Вызов getItems имеет пустой массив зависимостей, поэтому я бы все равно не ожидал увидеть больше одного журнала консоли. Как вы получаете три?

Ответ №1:

setTotalPrice(sum); не будет отражаться totalPrice немедленно, потому что функция настройки состояния является асинхронной. Вот почему console.log , похоже, не работает должным образом.

Кроме того, onSnapshot прослушиватель будет вызываться каждый раз, когда данные коллекции изменяются (добавляются / изменяются / удаляются). Вот пример для вашей информации.

 db.collection("cities").where("state", "==", "CA")
    .onSnapshot(function(snapshot) {
        snapshot.docChanges().forEach(function(change) {
            if (change.type === "added") {
                console.log("New city: ", change.doc.data());
            }
            if (change.type === "modified") {
                console.log("Modified city: ", change.doc.data());
            }
            if (change.type === "removed") {
                console.log("Removed city: ", change.doc.data());
            }
        });
    });