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

React中点击删除按钮为何会误删多个Input组件?

问题原因与解决方案

核心问题

你当前的实现存在两个关键问题:

  1. 直接将React组件实例存入state:React的state应当存储数据而非组件实例,直接存组件会破坏React的状态管理逻辑,导致diff算法无法正确识别组件身份。
  2. 用数组长度作为唯一标识/key:删除中间元素后,后续元素的key会因数组长度变化出现重复,React无法区分组件唯一性,加上过滤时直接比较组件的key属性,会触发误删。比如三个元素的key为0、1、2,删除key=1的元素后,剩余元素key为0、2,但数组长度变为2,React会混淆组件身份,最终导致多个组件被删除。

修复后的代码实现

App.js(修改后)

import React, { useState } from "react";
import Input from "./components/Input";

function App() {
  // 用数组存储数据项,每个项包含唯一id,后续可扩展存储运算符、数值等业务数据
  const [rows, setRows] = useState([]);

  // 生成唯一id,可改用uuid库提升严谨性
  const generateId = () => `${Date.now()}-${Math.random().toString(36).slice(2,9)}`;

  const addRow = (event) => {
    event.preventDefault();
    // 用函数式更新确保拿到最新state
    setRows(prevRows => [...prevRows, { id: generateId() }]);
  };

  const deleteRow = (rowId) => {
    setRows(prevRows => prevRows.filter(row => row.id !== rowId));
  };

  return (
    <div className="App">
      <div className="calculator">
        <h3>React calculator</h3>
        <button onClick={addRow}>Add row</button>
        <ul>
          {/* 基于数据动态生成组件,用唯一id作为key */}
          {rows.map(row => (
            <Input
              key={row.id}
              rowId={row.id}
              deleteRow={deleteRow}
            />
          ))}
        </ul>
        <div id="sumID" className="sum-styles"></div>
      </div>
    </div>
  );
}

export default App;

Input.js(修改后)

import React from "react";

const Input = (props) => {
  return (
    <li className="item">
      <select className="select__operator">
        <option value="+">+</option>
        <option value="-">-</option>
      </select>
      <div>
        <span className="num"></span>
        <input
          type="text"
          name="number"
          placeholder="Enter your number here..."
          className="input__number"
        />
      </div>
      {/* 传递唯一id触发删除 */}
      <button onClick={() => props.deleteRow(props.rowId)}>Delete</button>
      <button>Disable</button>
    </li>
  );
};

export default Input;

关键优化说明

  • 数据驱动渲染:state存储纯数据对象,组件通过map方法动态生成,这是React的标准实践,便于状态管理和后续扩展。
  • 唯一标识:用永不重复的id作为组件key和删除依据,确保React能精准识别每个组件,删除操作只会移除对应的数据项和组件。
  • 函数式更新state:更新状态时使用prevRows => ...的形式,避免因状态更新的异步性导致的逻辑错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 20:15:42