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

React中无法按索引删除动态div对应的数组指定元素如何解决?

问题原因

你当前的写法存在三个核心错误,这也是你删除一个元素就丢失后面所有元素的直接原因:

  1. 闭包陷阱:你每个列表项绑定的删除函数都捕获了列表项创建时的Children状态,这个状态是固定的旧值,不是最新的列表数组。比如你新增第7个元素时,当时的Children长度为6,后续你再新增到10个元素,点击第7个元素的删除按钮时,函数拿到的还是长度为6的旧数组,你操作旧数组更新状态后,就会把之后新增的所有元素都覆盖丢失。
  2. 不应该直接把生成好的JSX元素存储在useState中,React的状态应该只存放原始业务数据,UI由数据渲染生成,直接存储JSX会导致内部绑定的事件、状态全部固化,无法跟随数组变化同步更新。
  3. 每个删除按钮绑定的是列表项创建时的静态索引,你删除前面的元素后,后续列表项的实际索引已经发生变化,但按钮绑定的还是旧索引,会导致后续删除操作位置错乱。

修正方案

把状态改为存储列表原始数据,渲染时再遍历数据生成对应的UI,删除时根据数据的唯一标识操作数据即可,修正后的代码如下:

const { useState } = React;

function Check(){
  // state只存列表原始业务数据,不存储渲染后的JSX
  const [listData, setListData] = useState([])
    
  function RemArr(targetId){
    // 用函数式更新保证拿到最新的状态,过滤掉要删除的项
    setListData(prev => prev.filter(item => item.id !== targetId))
  } 
    
  function addList() {
    // 新增时给每个项加唯一标识,避免用索引做删除依据的不稳定问题
    setListData(prev => [...prev, {
      id: Date.now(),
      fix: false
    }])
  }

  return (<React.Fragment>
    <div>Check</div>
    {/* 遍历数据动态生成UI,每次渲染都会拿到最新的索引和绑定最新的事件 */}
    {listData.map((item, index) => (
      <React.Fragment key={item.id}>
        <button onClick={()=>RemArr(item.id)}>
          List {index}
        </button>
        <p></p>
        <input/>
        <p></p>
      </React.Fragment>
    ))}
    <button onClick={addList}>
      Add List 
    </button>
  </React.Fragment>)
}

ReactDOM.render(<Check />, document.body);

配套HTML代码保持不变:

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 03:15:04