如何统计嵌套数组营养标签数量?解决React重渲染警告
解决React中营养标签统计的重渲染问题及实现方案
为什么会出现"too many rerenders"警告?
你在JSX的map循环里直接调用setNutritionalInfoCount,每次组件渲染时都会触发状态更新,状态更新又会触发组件重新渲染,形成无限循环,因此抛出重渲染警告。永远不要在组件的渲染阶段(JSX表达式内)调用状态更新函数。
正确的实现步骤
1. 编写营养标签统计逻辑
先遍历数组统计每个标签的出现次数,同时完成缩写到显示全名的映射:
// 定义缩写与显示名称的映射关系 const nutritionNameMap = { ve: 'Ve', gf: 'Gluten free', veg: 'Veg', nuts: 'Nuts' }; // 统计标签数量的函数 const calculateNutritionCounts = (menu) => { return menu.reduce((counts, food) => { food.nutritionalInfo.forEach(tag => { const displayName = nutritionNameMap[tag]; counts[displayName] = (counts[displayName] || 0) + 1; }); return counts; }, {}); };
2. 在组件中缓存统计结果
使用useMemo缓存计算结果,避免每次渲染都重复计算,只有当foodMenu变化时才重新统计:
import { useMemo } from 'react'; function MenuNutritionStats() { const foodMenu = [ {id: 1, name: 'pasta', nutritionalInfo: ['ve', 'veg', 'gf']}, {id: 2, name: 'pizza', nutritionalInfo: ['gf', 'veg']}, {id: 3, name: 'applePie', nutritionalInfo: ['nuts']} ]; // 缓存统计结果,依赖foodMenu变化 const nutritionCounts = useMemo(() => calculateNutritionCounts(foodMenu), [foodMenu]); return ( <div> {/* 遍历渲染统计结果 */} {Object.entries(nutritionCounts).map(([name, count]) => ( <p key={name}>{`${name}: ${count}`}</p> ))} </div> ); }
3. 最终渲染效果
页面会输出:
Ve: 1 Gluten free: 2 Veg: 2 Nuts: 1
额外说明
如果foodMenu是从父组件传入的props,只需将其加入useMemo的依赖数组,即可确保数据更新时统计结果同步更新。这类统计结果属于衍生数据,完全可以通过原始数据计算得到,不需要用状态存储。
内容的提问来源于stack exchange,提问作者Jordan1993
相关产品推荐
相关产品推荐

