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

如何统计嵌套数组营养标签数量?解决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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 21:55:20