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

React中使用过滤器计算总收入时出现NaN问题求助

React过滤后计算总收入返回NaN的问题修复

问题梳理

在React应用中,尝试根据发行商过滤器计算歌曲总收入时出现NaN值,且过滤器逻辑、组件绑定、金额计算逻辑均存在错误,导致无法实现过滤后显示正确总金额的功能。

错误点分析

  1. 过滤器逻辑混乱

    • 错误将数字类型的totalRevenue与空字符串比较,totalRevenue === ""永远为false,导致过滤条件失效
    • 错误访问song.Distributor?.Revenue,Revenue是song的直接属性,并非Distributor的子属性
    • 逻辑或位置错误,错误将两个匹配条件写在同一个includes参数中
  2. Select组件绑定错误

    • Select的value错误绑定filterDistributor || totalRevenue,该组件仅用于选择发行商,应仅绑定filterDistributor
    • onChange事件错误尝试同时更新filterDistributor和totalRevenue,totalRevenue是计算结果,不应通过选择器直接修改
  3. 总收入计算未关联过滤结果
    原代码仅基于原始songs数组计算总收入,未使用过滤后的歌曲列表,导致过滤后总金额不更新

  4. 金额格式化精度丢失
    Math.round(totalRevenue).toFixed(2)会先将金额取整再保留两位小数,丢失小数部分精度

修正后的完整代码

import { useState, useEffect } from 'react';

const RevenueTable = ({ songs }) => {
  const [filterDistributor, setFilterDistributor] = useState("");
  // 分页相关状态(保留原有逻辑)
  const [songsPerPage] = useState(10);
  const [currentPage, setCurrentPage] = useState(1);
  const pagesVisited = (currentPage - 1) * songsPerPage;

  // 先计算过滤后的歌曲列表
  const filteredSongs = songs.filter((song) => {
    if (filterDistributor === "") return true;
    return song.Distributor?.toLowerCase().includes(filterDistributor.toLowerCase());
  });

  // 根据过滤后的歌曲计算总收入
  const [totalRevenue, setTotalRevenue] = useState(0);
  useEffect(() => {
    const total = filteredSongs.reduce((acc, song) => {
      const revenue = typeof song.Revenue === 'number' ? song.Revenue : Number(song.Revenue);
      return isNaN(revenue) ? acc : acc + revenue;
    }, 0);
    setTotalRevenue(total);
  }, [filteredSongs]);

  // 分页处理后的展示列表
  const displaySongs = filteredSongs
    .slice(pagesVisited, pagesVisited + songsPerPage)
    .map((song) => (
      <tr key={song.id} className="font-medium bg-white border-b dark:bg-gray-800 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600">
        <td className="py-2 px-4 text-left">{song.Distributor}</td>
        <td className="py-2 px-4 text-left">{song.Revenue.toFixed(4)}</td>
      </tr>
    ));

  return (
    <div>
      <div className="flex w-full">
        <select
          id="Labels"
          className="bg-slate-900 text-white border border-gray-500 text-sm focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
          value={filterDistributor}
          onChange={(e) => setFilterDistributor(e.target.value)}
        >
          <option value="">Choose a Distributor</option>
          {[...new Set(songs.map((song) => song.Distributor))].map((distributor) => (
            <option key={distributor} value={distributor}>
              {distributor}
            </option>
          ))}
        </select>
      </div>

      <div className="w-96 p-6 my-10 gap-4 shadow-md rounded-md bg-slate-900 text-center">
        <p className="font-normal text-white dark:text-gray-400">
          Total Revenue:
        </p>
        <p className="text-2xl font-bold tracking-tight text-white dark:text-white">
          {(Math.round(totalRevenue * 100) / 100).toFixed(2)} €
        </p>
      </div>

      {/* 完整表格结构 */}
      <table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
        <thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
          <tr>
            <th className="py-3 px-4">Distributor</th>
            <th className="py-3 px-4">Revenue</th>
          </tr>
        </thead>
        <tbody>
          {displaySongs}
        </tbody>
      </table>
    </div>
  );
};

export default RevenueTable;

关键修正说明

  1. 分离过滤与计算逻辑

    • 先生成filteredSongs过滤列表,确保过滤逻辑独立清晰
    • 总收入计算依赖filteredSongs,过滤条件变化时自动重新计算总金额
  2. 修复过滤器逻辑

    • 移除无效的totalRevenue === ""判断,仅保留发行商匹配逻辑
    • 正确访问song.Revenue属性
  3. 修正Select组件绑定

    • Select仅绑定filterDistributor状态,onChange仅更新该状态
  4. 优化金额处理

    • 先判断Revenue类型,避免不必要的类型转换
    • 使用(Math.round(totalRevenue * 100) / 100).toFixed(2)保证两位小数的精度
  5. 符合React规范

    • 列表渲染添加key={song.id}属性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 05:16:37