Home > Software design >  Firestore query snapshot forEach seems to be overwriting products state
Firestore query snapshot forEach seems to be overwriting products state

Time:01-04

I am trying to query my firestore database using getDocs() and using a state to store the products within the "category1" collection. This is to be able to render all the products within the "category1" collection using React.

This is my Category.jsx file:

import React, { useState, useEffect } from "react";
import Product from "./Product";
import { getDocs, collection } from "firebase/firestore";
import db from "../firebase.config";

function Category(props) {
  const [products, setProducts] = useState([]);

  const fetchProducts = async () => {
    const querySnapshot = await getDocs(collection(db, props.id));
    querySnapshot.docs.forEach((doc) => {
      setProducts([...products, { ...doc.data(), id: doc.id }]);
    });
  };

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

  return (
    <div>
      <h1>{props.name}</h1>
      {products &&
        products.map((product) => {
          const { productName, image, price, description } = product;
          return (
            <Product
              key={product.id}
              productName={productName}
              image={image}
              price={price}
              description={description}
            />
          );
        })}
    </div>
  );
}

export default Category;

My Firestore database contains these two documents:

{
description: "this is an example product",
id: "6B5RqpuTMwg4hRhmOSwZ",
image: "imagelink",
price: 199,
productName: "Product 1"
},

{
description: "this is another product",
id: "a4VUpJMTvwh9tDsFyaxy",
image: "imagelink",
price: 299,
productName: "Product 2"
}

The result is only Product 2 showing up. When I console.log(products) I can see that product 1 is inside the products state and then is replaced by product 2.

Thanks

CodePudding user response:

Calls to setProducts execute asynchronously, so the multiple calls you do likely are getting into each other's way.

const fetchProducts = async () => {
  const querySnapshot = await getDocs(collection(db, props.id));
  let theseProducts = querySnapshot.docs.map((doc) => {
    return { ...doc.data(), id: doc.id };
  })
  setProducts([...products, ...theseProducts]);
}
  •  Tags:  
  • Related