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

React中通过className求和显示NaN问题排查求助

解决通过className求和显示NaN的问题

问题背景

尝试通过className获取页面上的数值元素并求和展示,但结果始终显示NaN,原代码如下:

原求和逻辑代码

let hoursCompleted = document.getElementsByClassName('data-legend-info-part');

let totalHoursCompleted = [];

for (let i = 0; i < hoursCompleted.length; i++) {
const hours = hoursCompleted[i];
totalHoursCompleted.push(Number(hours));
}

let sum = 0;

for (let i = 0; i < totalHoursCompleted.length; i++) {
sum += totalHoursCompleted[i];
}

原React渲染代码

return (
<div className="pie-chart-wrapper">
<div id={`pie-chart-container-${pieChartId}`} className="pie-chart" />
<div>
<div className="pie-chart-legend-header">
<div>Name</div>
<div>{dataLegendHeader}</div>
</div>{/*Values for Name Header entered here*/}
{Object.keys(dataLegend).map(key => (
<div key={key} className="pie-chart-legend-item">
<div className="data-legend-color" style={{ backgroundColor: color(key) 
}} />
<div className="data-legend-info">
{dataLegend[key].map(legendPart => (
<div className="data-legend-info-part">{legendPart}</div>
))}
</div>
</div>
))}{/*Values for Hours Header entered here*/}

<div className="pie-chart-legend-item">
<div className="data-legend-info">
Total Hours Worked:
<div className="data-legend-info-part">{sum}</div>
</div>
</div>
</div>
</div>
);

期望效果:若有3个各4小时的任务,sum应显示12。


错误原因

  1. DOM元素直接转数字:代码中Number(hours)的hours是DOM元素对象,并非元素内的文本内容,转换后直接得到NaN。
  2. DOM操作时机错误:若在组件渲染完成前调用document.getElementsByClassName,此时DOM尚未生成,获取到的元素列表为空,求和自然出错。
  3. React反模式:直接从DOM提取数据不符合React的数据流理念,数据源dataLegend才是数据的唯一可信来源。

解决方法

方法1:从数据源直接计算(推荐,符合React设计模式)

直接遍历dataLegend计算总和,无需操作DOM,代码简洁且避免异步问题:

// 遍历数据源累加所有小时数
const sum = Object.values(dataLegend).reduce((total, legendParts) => {
  return total + legendParts.reduce((partTotal, part) => {
    // 处理非数字情况,转换失败时取0避免NaN
    return partTotal + (Number(part) || 0);
  }, 0);
}, 0);

方法2:修正DOM操作方式(不推荐,仅作参考)

若必须通过DOM获取,需确保在组件渲染完成后执行,使用useEffect监听数据源变化:

import { useEffect, useState } from 'react';

function YourComponent(props) {
  const [sum, setSum] = useState(0);
  const { dataLegend } = props;

  useEffect(() => {
    let total = 0;
    const elements = document.getElementsByClassName('data-legend-info-part');
    for (let elem of elements) {
      // 获取元素文本并转数字,处理无效值
      const value = Number(elem.textContent.trim());
      total += isNaN(value) ? 0 : value;
    }
    setSum(total);
  }, [dataLegend]); // 数据源变化时重新计算

  // 后续渲染代码不变
  return (
    // ... 原渲染内容
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 09:11:19