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

如何在JavaScript中更新数组内特定对象的属性值

问题根因
  • 状态数组引用未发生变化:你直接将原状态数组localPreRoutingCall赋值给localArray,二者指向同一个内存地址,调用splice修改数组后引用没有变更,React浅比较判定状态未更新,不会触发组件重渲染。
  • 循环渲染未添加唯一key:map遍历渲染元素时没有给外层包裹元素添加key属性,可能导致React Diff算法无法正确识别需要更新的节点。
  • 冗余的e.persist():React17及之后版本已经移除了合成事件池机制,该调用已经没有实际作用。
修复方案

1. 修正状态更新函数

修改changeObjectValue,遵循React不可变更新原则,先拷贝原数组生成新的数组实例,再修改新数组后更新状态,推荐用更简洁的map方式实现:

const changeObjectValue = (value, targetItem) => {
  setLocalPreRoutingCall(prev => prev.map(item => {
    return item.id === targetItem.id ? {...item, value} : item
  }))
};

如果要保留原有的lodash查找逻辑,也可以修改为:

const changeObjectValue = (value, item) => {
  console.log("@@ array", value);
  // 浅拷贝原数组生成新实例
  let localArray = [...localPreRoutingCall];
  const index = _.findIndex(localArray, { id: item.id });
  if (index !== -1) {
    localArray[index] = { ...item, value: value };
    setLocalPreRoutingCall(localArray);
  }
};

2. 给循环渲染项添加唯一key

修改map渲染部分,给外层的Fragment添加唯一key属性:

localPreRoutingCall &&
    localPreRoutingCall.map((item, index) => (
      // 优先用item.id作为key,仅当数组不会发生增删、排序操作时可临时用index替代
      <React.Fragment key={item.id}>
        <div className="pre-route-title">{item?.field_title}</div>
        <textarea
          placeholder="Enter something"
          className="pre-route-textarea"
          value={item?.value}
          onChange={(e) => {
            changeObjectValue(e.target.value, item);
          }}
        />
        <div className="pre-route-description">
          {item?.description}
        </div>
      </React.Fragment>
    ))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 13:57:02