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

React中渲染来自多Firestore集合的分类式对象数组的实现方案

解决Firestore多集合数据获取与渲染问题

我来帮你搞定这个需求!先看你代码里的几个关键问题,调整后再实现渲染逻辑:

一、修正数据获取逻辑

你的代码里有几个影响React状态更新和数据完整性的问题,先把这些搞定:

  1. 别直接修改初始的categories对象,React状态更新必须用setFoods才能触发重渲染
  2. 避免用fetch当自定义函数名(这是JS内置API),改成fetchFoods更稳妥
  3. 所有Firestore请求都是异步的,得用Promise.all等所有请求完成后再统一更新状态,不然会出现数据不完整的情况

修正后的完整数据获取代码:

import { useState, useEffect } from 'react';

// 初始化分类结构,单独抽出来避免重复引用
const initialCategories = { 
  Pakoras: [], 
  Vegitarisches: [], 
  "Biryani Gerichte": [], 
  Hähnchengerichte: [], 
  "Indische Beilagen": [], 
  Lammgerichte: [], 
  "Ben & Jerrys": [], 
  Getränke: [], 
  Pizza: [], 
  Kindermenüs: [], 
  Spaghetti: [], 
  Tortellini: [], 
  Gnochi: [], 
  Maccheroni: [], 
  Tagliatelle: [], 
  "Überbackene Nudeln": [], 
  Salate: [], 
  Fleischgerichte: [], 
  "Schnitzel & Fleischgerichte": [], 
  Risotto: [], 
  "Überbackenes-Gemüse-Kartoffeln": [], 
  "Chinesische-Gerichte-Gebratene-Nudeln-Reis": [], 
};

export default function FoodMenu() {
  const [foods, setFoods] = useState(initialCategories);

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

  async function fetchFoods() {
    console.log("Fetching");
    // 收集所有集合的请求Promise
    const fetchTasks = Object.keys(initialCategories).map(async (category) => {
      const snapshot = await fire.firestore().collection(category).get();
      // 把文档数据转换成数组
      const foodItems = snapshot.docs.map(doc => doc.data());
      return { category, foodItems };
    });

    // 等待所有请求完成
    const results = await Promise.all(fetchTasks);
    
    // 整理成目标格式的对象
    const updatedFoods = results.reduce((acc, { category, foodItems }) => {
      acc[category] = foodItems;
      return acc;
    }, {...initialCategories});

    // 更新状态,触发React重渲染
    setFoods(updatedFoods);
  }

  // 渲染逻辑写在这里
}

二、实现分类渲染逻辑

现在可以用Object.entries遍历foods对象,按分类展示每个食物的信息:

// 接上面的组件代码,添加return部分
return (
  <div className="food-menu-container">
    {Object.entries(foods).map(([categoryName, foodList]) => (
      <div key={categoryName} className="category-group">
        <h2>{categoryName}</h2>
        <div className="food-items">
          {foodList.map((food, idx) => (
            <div key={idx} className="food-item">
              <strong>{food.title}</strong> - 
              <span> {food.price}€</span> - 
              <span> {food.desc}</span>
            </div>
          ))}
        </div>
      </div>
    ))}
  </div>
);

小提示:

  • 如果你的food对象有唯一id(比如Firestore文档的id),把key={idx}改成key={food.id}会更符合React的性能优化要求
  • 可以给.category-group、.food-item这些类名加CSS样式,让页面布局更美观

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 07:04:10