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

React:如何在setState中更新对象数组单个元素并修复输入同步问题

问题修复方案

问题根源

  1. 输入框同步显示:所有输入框共用同一个addTagValue状态,导致输入时所有框内容完全一致。
  2. 添加目标错误:handleClick中硬编码只修改索引为0的对象,无论点击哪个按钮,新元素只会被加到第一个对象的synonyms列表里。

修复后的代码

import React, { useState } from "react";

export default function App() {
  const initialSynonyms = [
    { id: 1, keyword: "Caffeine", synonyms: ["Coffee", "Espresso"] },
    { id: 2, keyword: "Drowsiness", synonyms: ["Sleeping", "Fatigue"] },
    { id: 3, keyword: "Drowsiness", synonyms: [""] }
  ];
  const [mysynonyms, setSynonyms] = useState(() => initialSynonyms);
  // 用对象存储每个词条对应的输入值,以词条id作为键
  const [addTagValues, setAddTagValues] = useState(() => 
    initialSynonyms.reduce((acc, item) => {
      acc[item.id] = "";
      return acc;
    }, {})
  );

  // 接收词条id,更新对应输入框的内容
  const handleChange = (id, e) => {
    setAddTagValues(prev => ({
      ...prev,
      [id]: e.target.value
    }));
  };

  // 接收词条id,找到对应词条并添加新同义词
  const handleClick = (id) => {
    setSynonyms(prevValue => 
      prevValue.map(item => {
        if (item.id === id) {
          return {
            ...item,
            synonyms: [...item.synonyms, addTagValues[id]]
          };
        }
        return item;
      })
    );
    // 清空当前词条对应的输入框
    setAddTagValues(prev => ({
      ...prev,
      [id]: ""
    }));
  };

  return (
    <div className="App">
      {mysynonyms.map((item) => {
        return (
          // 添加唯一key,避免React列表渲染警告
          <div key={item.id}>
            <p>{item.keyword}</p>

            {item.synonyms.map((synonym, idx) => (
              <span
                key={idx}
                style={{ border: "1px solid red", padding: "1px 1px 5px 7px", marginRight: "4px" }}
              >
                {synonym} x
              </span>
            ))}
            <div style={{ marginTop: "8px", marginBottom: "16px" }}>
              <input
                value={addTagValues[item.id]}
                className="form-control bg-color2 text-color7 border-end-0 fs-14 fw-bold"
                type="text"
                onChange={(e) => handleChange(item.id, e)}
              />
              <button onClick={() => handleClick(item.id)} style={{ marginTop: "4px" }}>add tag</button>
            </div>
          </div>
        );
      })}
    </div>
  );
}

关键修改点

  • 拆分输入状态:将单个addTagValue改为对象addTagValues,每个词条的id对应独立的输入值,彻底解决输入框同步问题。
  • 事件传参明确目标:handleChange和handleClick都接收词条id,精准定位要操作的词条,避免添加错误。
  • 正确更新对象结构:修改同义词列表时,展开原词条对象,避免原代码中出现的对象嵌套错误。
  • 添加唯一key:按照React规范给列表元素添加key,避免渲染异常和控制台警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 01:25:38