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

React触发onChange更新对象数组值时前序输入数据丢失如何解决

问题根因
  • 你每次触发修改时都从初始的dummy数组复制数据生成新数组,没有使用当前已经修改过的状态data作为基准,所以每次新的修改都会重置之前的修改内容
  • 渲染表格时遍历的是初始dummy数组而非状态中的data,且输入框未绑定value属性,视图和状态数据没有形成联动
修复后可运行代码
import React, { useState } from 'react';
import { render } from 'react-dom';

const App = () => {
  // 初始状态直接赋值初始数组
  const [data, setData] = useState([
    { DETAIL_REQUEST_ID: 1, STATUS: "REJECT", NOTE: "" },
    { DETAIL_REQUEST_ID: 2, STATUS: "REJECT", NOTE: "" },
    { DETAIL_REQUEST_ID: 3, STATUS: "REJECT", NOTE: "" },
  ]);

  const handleBtn = () => {
    console.log("DATA: ", data);
  };

  const handleChange = (e, id) => {
    // 基于当前最新的state数据生成新数组,保留之前的修改
    const updatedArr = data.map(el => {
      if (id === el.DETAIL_REQUEST_ID) {
        return { ...el, NOTE: e.target.value };
      }
      return el;
    });
    setData(updatedArr);
  };

  return (
    <div>
      <table>
        <tr>
          <th>Detail Request Id</th>
          <th>Note</th>
        </tr>
        {/* 遍历状态中的data,而非初始静态数组 */}
        {data.map(val => {
          return (
            <tr key={val.DETAIL_REQUEST_ID}>
              <td>{val.DETAIL_REQUEST_ID}</td>
              <td>
                {/* 绑定value属性,变成受控组件保证数据视图同步 */}
                <input 
                  type="text" 
                  value={val.NOTE}
                  onChange={(e) => handleChange(e, val.DETAIL_REQUEST_ID)} 
                />
              </td>
            </tr>
          )
        })}
      </table>
      <button type="submit" onClick={handleBtn}>Submit</button>
    </div>
  );
}

render(<App />, document.querySelector('#app'));
核心修改说明
  • 初始状态直接使用目标数组初始化,无需额外声明静态的dummy变量
  • 处理修改逻辑时以当前最新的data状态为基准生成新数组,保留所有历史修改记录
  • 渲染时遍历状态中的data,同时给输入框绑定value属性,将非受控组件转为受控组件,确保视图和状态数据完全同步
  • 补充了列表渲染必填的key属性,避免React渲染警告

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 06:18:02