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

React中删除按钮误删全部数组项而非单个的问题排查

问题分析与解决方案

你的filter函数语法没问题,但核心错误在于state存储的是React元素而非数据,且使用数组长度作为key/myKey,导致删除操作后key重复,React的diff算法识别错误,出现删除多行的情况。

为什么会出现这个问题?

  1. 你直接把<Input>元素存在newRow数组里,用newRow.length作为key。当删除中间行(比如第二行,key=1),剩下的第三行key还是2,但此时数组长度变为2,后续渲染时React会因为key的匹配问题,误判组件身份,导致错误删除。
  2. React元素的key是内部特殊属性,直接访问input.key的方式不可靠,且这种存储元素的方式违背React的状态管理原则。

正确的修改方案

1. 重构App.js:存储数据而非React元素

用state存储行数据(每个行带唯一ID),渲染时通过map生成Input组件,使用稳定的唯一ID作为key。

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

function App() {
  // 存储行数据,每个项是带唯一id的对象
  const [rows, setRows] = useState([]);
  // 用自增计数器生成唯一id,避免重复
  const [nextRowId, setNextRowId] = useState(0);

  const addRow = (event) => {
    event.preventDefault();
    // 添加新行数据,用唯一id
    setRows([...rows, { id: nextRowId }]);
    setNextRowId(nextRowId + 1);
  };

  const deleteRow = (rowId) => {
    // 根据id过滤行数据,逻辑清晰且可靠
    setRows(rows.filter(row => row.id !== rowId));
  };

  return (
    <div>
      <h3>React calculator</h3>
      <button onClick={addRow}>Add row</button>
      <ul>
        {/* 遍历数据生成Input组件,用唯一id作为key */}
        {rows.map(row => (
          <Input
            key={row.id}
            rowId={row.id}
            deleteRow={deleteRow}
          />
        ))}
      </ul>
    </div>
  );
}

export default App;

2. 调整Input.js:修复小问题

  • 移除未定义的addition/subtraction ref(代码中未使用)
  • 修正disableRow中disabled赋值为布尔值(而非字符串)
import "./Input.css";
import React, { useState, useRef } from "react";

const Input = (props) => {
    const inputRef = useRef();
    const [numbers, setNumbers] = useState();

    const disableRow = () => {
        // disabled是布尔属性,直接赋值true/false
        inputRef.current.disabled = true;
    };

    const calculator = () => {
        const inputValue = inputRef.current.value;
        setNumbers(inputValue);
    };

    return (
        <li className="item">
            <select>
                <option value="+">+</option>
                <option value="-">-</option>
            </select>
            <input type="number" ref={inputRef} onChange={calculator}/>
            <button onClick={() => props.deleteRow(props.rowId)}>Delete</button>
            <button onClick={disableRow}>Disable</button>
            {numbers}
        </li>
    );
};

export default Input;

为什么这样改?

  • 状态存储数据而非UI元素,符合React单向数据流原则,状态管理更清晰。
  • 使用唯一且稳定的ID作为key,确保React能准确识别每个组件,删除操作不会出现误判。
  • filter函数现在针对数据ID过滤,逻辑准确可靠。

内容的提问来源于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 17:27:30