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

Antd List组件删除列表项时始终移除最后一项问题排查

问题原因

出现「state数据正确但始终渲染删除最后一项」的问题,核心是两个错误:

  • 列表项缺失唯一key属性:React虚拟DOM对比时依赖key识别节点,你没有手动绑定key的情况下,React默认用数组索引作为匹配依据。当你删除非末尾项时,被删项之后的所有元素索引都会前移,React会误判你删除的是最后一个节点,直接复用前面的节点DOM,就会出现渲染错位。
  • 代码存在多处不规范/错误的状态操作:
    • 删除逻辑中错误将state更新函数setEmployeeList赋值给新列表变量,属于语法错误
    • 输入框修改逻辑直接修改原state对象的属性,还传入了未定义的answerList变量触发更新,违反React不可变数据原则
    • 输入框使用defaultValue作为非受控组件,状态更新时不会同步刷新输入框内容,进一步加剧渲染不一致问题
修复步骤
  1. 给每一条员工数据增加全局唯一的标识字段(比如新增时生成时间戳、自增ID,不要用数组索引)
  2. 所有state更新都遵循不可变原则:不直接修改原state的数组/对象,始终生成新的引用再传给更新函数
  3. 给<List.Item>绑定和数据唯一标识对应的key属性
  4. 输入框改为受控组件,用value替代defaultValue,保证视图和状态完全同步
修复后完整代码
const [employeeList, setEmployeeList] = useState([])

// 新增员工示例逻辑
const handleAdd = () => {
  setEmployeeList(prev => [
    ...prev,
    {
      id: Date.now(), // 用时间戳作为唯一ID,复杂场景可替换为uuid
      name: ''
    }
  ])
}

<List
  dataSource={employeeList}
  renderItem={(item) => (
   <List.Item key={item.id}>
     <Input 
      id='listItem-input'
      value={item.name} 
      onChange={(e) => {
        setEmployeeList(prev => prev.map(emp => {
          return emp.id === item.id ? {...emp, name: e.target.value} : emp
        }))   
      }}
    />
    <span className='removeItem' 
      onClick={() => {
        setEmployeeList(prev => prev.filter(emp => emp.id !== item.id))
       }}
     >
       <CloseOutlined/>
     </span>
   </List.Item>
 )}
/>

重要提示:只要列表存在增删、排序、拖拽调整顺序的操作,绝对不能用数组索引作为item的key,否则必然会出现DOM复用错误、渲染错位、状态绑定混乱的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 09:36:37