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]);
}
