You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firestore在JavaScript中返回空数组问题求助

问题:Firestore获取数据返回空数组,React组件无法渲染产品信息

我需要从Firestore获取数据并以JSX形式展示,因此在代码中使用了useEffect,期望所有Promise完成后再渲染React组件。手动定义JavaScript对象数据时组件可正常运行,说明问题出在Firestore返回空数组,而非React代码。

以下是我的代码:

import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";

import { addDoc, collection, onSnapshot } from "firebase/firestore";
import { db } from "../data/firestore-data";

import { UserAuth } from "../context/AuthContext";

export default function ProductPage() {
  const [products, setProducts] = useState([]);

  useEffect(() => {
    const productsRef = collection(db, "products");

    getDocs(productsRef).then((res) => {
      const ords = res.docs.map((doc) => ({
        data: doc.data(),
        id: doc.id,
      }));

      const products = ords.map((ord) => ({
        id: ord.id,
        name: ord.data.name,
        price: ord.data.price,
        imageSrc: ord.data.imageSrc,
        imageAlt: ord.data.imageAlt,
        productDescription: ord.data.productDescription,
      }));

      setProducts(products);
    });
  }, []);

  const productID = useParams().id;
  console.log(productID);

  const [count, setCount] = useState(1);

  const incrementCount = () => {
    setCount(count + 1);
  };

  const decrementCount = () => {
    if (count >= 2) {
      setCount(count - 1);
    }
  };

  console.log("Template : ");
  console.log(products);
  const product = products.find((obj) => obj.id === productID);
  const productName = product.name;
  const productPrice = product.price;
  const img = product.imageSrc;
  const productDescription = product.productDescription;

  const imgSize = 600;

  const { user } = UserAuth();

  function AddOrder() {
    console.log("Working...");
    const ordersRef = collection(db, "orders");
    addDoc(ordersRef, {
      ProductID: productID,
      UserID: user.uid,
    }).then((res) => {
      console.log(res);
    });
  }

  return (
    <React.Fragment>
      <div className="m-[70px] ml-[130px] flex flex-row items-start font-mono">
        <img
          className="mt-0 rounded-lg"
          style={{ width: imgSize, height: imgSize }}
          src={img}
          alt={productName}
        />
        <div className="mx-[90px] flex-grow space-y-9">
          <h1 className="text-5xl">{productName}</h1>
          <p className="text-lg font-bold">Available At: ${productPrice}</p>
          <p className="text-lg">{productDescription}</p>
          <div className="flex space-x-3">
            <div className="inline-flex h-[50px] flex-grow basis-1/4 items-center justify-center space-x-4 py-2 px-4">
              <button
                className="h-[25px] w-[25px] border-2 border-solid border-orange-600 text-center hover:bg-orange-600"
                onClick={decrementCount}
              >
                -
              </button>
              <span className="text-center text-xl text-black">{count}</span>
              <button
                className="h-[25px] w-[25px] border-2 border-solid border-orange-600 text-center hover:bg-orange-600"
                onClick={incrementCount}
              >
                +
              </button>
            </div>
            <button className="h-[50px] flex-grow basis-3/4 items-center rounded bg-orange-600 py-2 px-4 hover:bg-orange-500">
              <button
                className="text-center text-xl font-bold text-white"
                onClick={AddOrder}
              >
                Buy Now
              </button>
            </button>
          </div>
        </div>
      </div>
    </React.Fragment>
  );
}

当上述代码无效时,我尝试使用onSnapshot函数,但仍返回空数组,对应代码如下:

useEffect(() => {
  const productsRef = collection(db, "products");
  onSnapshot(productsRef, (snapshot) => {
    setProducts(
      snapshot.docs.map((doc) => ({
        id: doc.id,
        name: doc.data.name,
        price: doc.data.price,
        imageSrc: doc.data.imageSrc,
        imageAlt: doc.data.imageAlt,
        productDescription: doc.data.productDescription,
      }))
    );
  });
}, []);

控制台报错是因为尝试访问空数组中的对象属性,待空数组问题解决后报错会消失,两种方法的控制台输出均为相同的空数组。若需要其他上下文或导入文件代码,请告知。

内容的提问来源于stack exchange,提问作者user14460193

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 21:53:14