React中渲染来自多Firestore集合的分类式对象数组的实现方案
解决Firestore多集合数据获取与渲染问题
我来帮你搞定这个需求!先看你代码里的几个关键问题,调整后再实现渲染逻辑:
一、修正数据获取逻辑
你的代码里有几个影响React状态更新和数据完整性的问题,先把这些搞定:
- 别直接修改初始的
categories对象,React状态更新必须用setFoods才能触发重渲染 - 避免用
fetch当自定义函数名(这是JS内置API),改成fetchFoods更稳妥 - 所有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
相关产品推荐
相关产品推荐

