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

React中如何计算筛选后表格列的总价?

React 筛选表格计算筛选后总价问题

我在React中实现了一个带筛选功能的简易表格,表格仅包含汽车的name和price字段,通过下拉选择框按汽车名称进行筛选。我需要展示筛选后汽车的总价,但尝试通过操作DOM计算总价的函数返回无效值。

尝试的函数代码:

const updateSubTotal = () => {
        var table = document.getElementById("myTable");
        let subTotal = Array.from(table.rows)
          .slice(1)
          .reduce((total, row) => {
            return total + parseFloat(row.cells[1].innerHTML);
          }, 0);
        setTot(subTotal);
      };

完整代码:

import { useState } from "react";
import "./styles.css";
const data = [
  {
    name: "Saab",
    price: 100
  },
  {
    name: "Mercedes",
    price: 50
  },
  {
    name: "Audi",
    price: 10
  }
];
export default function App() {
  const [tot, setTot] = useState();

  const updateSubTotal = () => {
    var table = document.getElementById("myTable");
    let subTotal = Array.from(table.rows)
      .slice(1)
      .reduce((total, row) => {
        return total + parseFloat(row.cells[1].innerHTML);
      }, 0);
    setTot(subTotal);
  };
  //CALCULATE sum of prices
  const totalPrice = data.map((item) => item.price).reduce((a, b) => a + b, 0);
  const [searchValue, setSearchValue] = useState("");
  const DisplayData = data
    ?.filter((row) => row?.name?.match(new RegExp(searchValue, "i")))
    .map((cars) => {
      return (
        <tr key={cars.name}>
          <td>{cars?.name}</td>
          <td>{cars?.price}</td>
        </tr>
      );
    });
  return (
    <div className="App">
      <label for="cars">Choose a car:</label>
      <select
        name="cars"
        id="cars"
        value={searchValue}
        onChange={(e) => {
          setSearchValue(e.target.value);
          updateSubTotal();
        }}
      >
        <option value="saab">Saab</option>
        <option value="mercedes">Mercedes</option>
        <option value="audi">Audi</option>
      </select>
      <table className="tables" id="myTable">
        <thead className="sticky-header overflow-hidden z-50">
          <tr>
            <th className="">Car Name</th>
            <th className="">Price</th>
          </tr>
        </thead>
        <tbody>{DisplayData}</tbody>
      </table>
      <div>Total Price without filter: {totalPrice}</div>
      <div>Total Price after filter: {tot}</div>
    </div>
  );
}

问题原因及解决方案

问题出在React状态更新的异步性:调用setSearchValue后,组件不会立即重新渲染,此时DOM还没更新为筛选后的内容,updateSubTotal操作DOM拿到的还是旧数据,导致计算结果错误。在React中应避免直接操作DOM获取数据,而是基于状态和原始数据计算结果。

修改后代码:

import { useState } from "react";
import "./styles.css";
const data = [
  {
    name: "Saab",
    price: 100
  },
  {
    name: "Mercedes",
    price: 50
  },
  {
    name: "Audi",
    price: 10
  }
];
export default function App() {
  const [searchValue, setSearchValue] = useState("");
  
  // 先获取筛选后的数据集合
  const filteredData = data?.filter((row) => 
    row?.name?.match(new RegExp(searchValue, "i"))
  );
  
  // 基于筛选后的数据计算总价
  const filteredTotal = filteredData.reduce((total, item) => total + item.price, 0);
  
  // 计算全部汽车总价
  const totalPrice = data.reduce((a, b) => a + b.price, 0);

  const DisplayData = filteredData.map((cars) => {
    return (
      <tr key={cars.name}>
        <td>{cars?.name}</td>
        <td>{cars?.price}</td>
      </tr>
    );
  });

  return (
    <div className="App">
      <label htmlFor="cars">Choose a car:</label>
      <select
        name="cars"
        id="cars"
        value={searchValue}
        onChange={(e) => setSearchValue(e.target.value)}
      >
        <option value="saab">Saab</option>
        <option value="mercedes">Mercedes</option>
        <option value="audi">Audi</option>
      </select>
      <table className="tables" id="myTable">
        <thead className="sticky-header overflow-hidden z-50">
          <tr>
            <th>Car Name</th>
            <th>Price</th>
          </tr>
        </thead>
        <tbody>{DisplayData}</tbody>
      </table>
      <div>Total Price without filter: {totalPrice}</div>
      <div>Total Price after filter: {filteredTotal}</div>
    </div>
  );
}

关键修改点:

  • 提取filteredData变量,复用筛选后的数据,既用于渲染表格,也用于计算总价
  • 通过filteredData.reduce直接计算总价,完全避免操作DOM,结果准确且符合React状态驱动的理念
  • 移除冗余的tot状态和updateSubTotal函数,简化代码逻辑
  • 修正label的for属性为React规范的htmlFor,避免JSX关键字冲突

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 02:35:18