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

如何在Input的onChange事件中单独修改数组项并实现值求和

问题描述

我有如下对象列表:

[
  {id: 182, symbol: 'ETHUSDT', recommended_to_buy_qty: '42.83213', current_qty_in_portfolio: '8.06928'},
  {id: 183, symbol: 'XRPUSDT', recommended_to_buy_qty: '83.47332', current_qty_in_portfolio: '8.79834'},
  {id: 184, symbol: 'ADAUSDT', recommended_to_buy_qty: '50.72704', current_qty_in_portfolio: '3.79095'}
]

需求是在Input的onChange事件中对数组中每个项的数值进行计算(比如输入值与现有持仓量求和),每次输入变化时重新计算对应项的总和。但目前用单个inputValue状态绑定所有输入控件,导致所有输入值同步变化,想实现每次onChange仅修改数组中的单个项。

当前代码:

const [inputValue, setInputValue] = useState(0)

function handleChange(e) {
    e.preventDefault();
    setInputValue(e.target.value);
}

输入控件:

<Form.Control onChange={handleChange} value={inputValue} />
解决方案

1. 将整个持仓数组设为状态

把单个inputValue替换为包含所有持仓项的数组状态,给每个项新增inputQty字段存储对应输入框的值:

const [portfolioItems, setPortfolioItems] = useState([
  {id: 182, symbol: 'ETHUSDT', recommended_to_buy_qty: '42.83213', current_qty_in_portfolio: '8.06928', inputQty: 0},
  {id: 183, symbol: 'XRPUSDT', recommended_to_buy_qty: '83.47332', current_qty_in_portfolio: '8.79834', inputQty: 0},
  {id: 184, symbol: 'ADAUSDT', recommended_to_buy_qty: '50.72704', current_qty_in_portfolio: '3.79095', inputQty: 0}
]);

2. 修改事件处理函数,绑定项的唯一标识

让handleChange接收当前项的id,精准定位要更新的项:

function handleChange(id, e) {
  const newValue = e.target.value;
  // 遍历数组,只更新对应id的项
  setPortfolioItems(prevItems => 
    prevItems.map(item => 
      item.id === id 
        ? {...item, inputQty: Number(newValue)} 
        : item
    )
  );
}

3. 映射生成独立的输入控件

遍历数组生成输入控件,每个控件绑定对应项的id和inputQty值,同时展示计算后的总和:

{portfolioItems.map(item => (
  <div key={item.id}>
    <span>{item.symbol}</span>
    <Form.Control 
      onChange={(e) => handleChange(item.id, e)} 
      value={item.inputQty}
      type="number"
    />
    {/* 显示当前项的输入值+持仓量总和 */}
    <p>当前总和:{(Number(item.inputQty) + Number(item.current_qty_in_portfolio)).toFixed(5)}</p>
  </div>
))}

4. 计算全局总和(可选)

如果需要统计所有项的总和,用useMemo缓存计算结果,避免重复渲染:

import { useMemo } from 'react';

const totalSum = useMemo(() => {
  return portfolioItems.reduce((sum, item) => {
    return sum + Number(item.inputQty) + Number(item.current_qty_in_portfolio);
  }, 0).toFixed(5);
}, [portfolioItems]);

// 渲染全局总和
<div>全局总持仓:{totalSum}</div>
关键说明
  • 不要用单个状态管理多个输入控件,让每个输入对应数组中单个项的字段,确保输入变化只影响对应项。
  • 更新数组状态时,返回新的对象(用扩展运算符...),保证React能检测到状态变化并重新渲染。
  • 数值计算前要把字符串转为数字(Number()),避免字符串拼接导致错误结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 11:25:15