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

React删除组件后状态错乱求助:删除id=2后id=3值异常

问题原因分析
  1. 列表渲染缺少唯一key:你在idArray.map渲染Component时未指定key属性,React默认用数组索引作为key。删除id=2的项后,原数组变为[1,3],map遍历索引0对应id=1、索引1对应id=3,但React会复用原索引1的组件实例(即之前id=2的组件),该组件的状态仍为val2,因此出现id=3的输入显示val2的错位问题。
  2. 状态分散存储:每个Component单独维护description局部状态,未将状态与对应id绑定到全局状态中,导致组件复用时,状态无法匹配正确的id。
解决方法

1. 为列表项添加唯一key

在map渲染Component时,将id作为key传入,让React精准识别每个组件实例:

let components = idArray.map((id) => {
  return (
    <Component key={id} id={id} />
  );
})

2. 统一管理所有输入状态

将所有输入框的值存入全局Context的状态中,以id为键建立映射,替代组件局部状态。

调整Context状态结构

更新Context的初始状态,新增values对象存储每个id对应的输入值:

const initialState = {
  idArray: [],
  values: {},
  setIdArray: () => {},
  setValues: () => {}
};

修改Display组件

引入全局values状态,同时用React状态管理count(避免全局变量的不可预测性):

export default function Display() {
  const { idArray, setIdArray, values, setValues } = useContext(Context);
  const [count, setCount] = useState(1);

  let components = idArray.map((id) => {
    return (
      <Component key={id} id={id} />
    );
  });

  const handleFirstInputChange = ({ detail }) => {
    setValues(prev => ({ ...prev, 1: detail.value }));
  };

  return (
    <>
      <div id="component-1">
        <input
          className="className"
          id="1"
          type="text"
          onChange={handleFirstInputChange}
          value={values[1] || ""}
          placeholder="Enter description"
        />
        {components}
      </div>
      <button
        iconName="add-plus"
        onClick={() => {
          const newCount = count + 1;
          setCount(newCount);
          setIdArray(previousIdArray => [...previousIdArray, newCount]);
          setValues(prev => ({ ...prev, [newCount]: "" }));
        }}
      />
    </>
  );
}

修改Component组件

移除局部description状态,直接使用全局values,修改时同步更新全局状态:

export default function Component(props) {
  const { idArray, setIdArray, values, setValues } = useContext(Context);
  const { id } = props;

  function removeRow() {
    const newArray = idArray.filter((i) => i !== id);
    setIdArray(newArray);
    setValues(prev => {
      const newValues = { ...prev };
      delete newValues[id];
      return newValues;
    });
  }

  const handleInputChange = ({ detail }) => {
    setValues(prev => ({ ...prev, [id]: detail.value }));
  };

  return (
    <div id={id}>
      <input
        className="className"
        id={id}
        type="text"
        onChange={handleInputChange}
        value={values[id] || ""}
        placeholder="Enter description"
      />
      <button
        iconName="cross"
        onClick={removeRow}
      />
    </div>
  );
}

补充说明

  • 用useState管理count替代全局变量,确保组件重新渲染时count状态可靠,避免多实例下的冲突。
  • 统一状态管理后,每个输入框的值与id绑定,删除操作仅移除对应id的状态,彻底解决状态错位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 04:05:01