React下合并食谱食材数组并计算总需求量的实现方案
最优实现方案
总食材需求量是menu的派生状态,完全不需要额外维护total、indexCount两个state,也不需要写多分支判断的useEffect,直接用useMemo计算即可,逻辑更简洁也不会出现状态同步bug:
// 仅依赖menu自动计算总食材,menu更新时自动重新计算 const totalIngredients = React.useMemo(() => { // 1. 把所有食谱的食材合并成一个一维数组 const allIngredients = menu.flatMap(recipe => recipe.ingredients) // 2. 用 食材名+单位 做key聚合,避免同食材不同单位累加错误 const ingredientMap = {} allIngredients.forEach(ing => { const uniqueKey = `${ing.ingName}_${ing.unit}` if (ingredientMap[uniqueKey]) { ingredientMap[uniqueKey].quantity = Number(ingredientMap[uniqueKey].quantity) + Number(ing.quantity) } else { // 拷贝原数据避免修改原始食谱信息 ingredientMap[uniqueKey] = {...ing, quantity: Number(ing.quantity)} } }) // 3. 转成数组就是最终统计结果 return Object.values(ingredientMap) }, [menu]) // 如果需要输出你示例中的字符串格式,直接处理即可 const totalText = `total : ${totalIngredients.map(ing => `${ing.ingName} ${ing.quantity}${ing.unit}`).join(' , ')}`
同时你不需要修改最初版本的按钮代码,不用额外加setCount逻辑,减少冗余代码。
方案优势
- 无额外状态维护,从根源避免了
indexCount和menu不同步、total累加时序错误的问题 - 没有分支判断,不管菜单里加了多少份食谱都能正确统计
- 用「食材名+单位」做聚合key,比只匹配食材名更严谨,避免出现比如鸡蛋同时存在「个」和「千克」两种单位时累加错误的问题
- 性能足够,只有
menu更新时才会重新计算,即使菜单内有几十上百份食谱也不会有性能压力
内容的提问来源于stack exchange,提问作者Deniz Firat
相关产品推荐
相关产品推荐

