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

React DOM状态变更后未正确更新问题排查

React列表删除项显示异常问题解决

问题现象

多次点击“Add Button”创建列表后,点击列表项旁的“Delete”按钮删除指定项时,State已正确更新且该项已从列表中移除,但页面显示最后一项被删除,而选中的项仍保留。

问题原因

  1. 缺少唯一key属性:React列表渲染时依赖key识别元素唯一性,你在map生成列表项时未添加key,导致React的Diff算法无法正确追踪元素变化。删除某一项后,后续元素索引发生变化,React会错误复用DOM元素,造成视觉显示异常。
  2. 状态更新的闭包风险:删除操作中直接基于当前渲染周期的records.data创建新数组,虽使用了函数式更新,但仍存在捕获旧state值的潜在问题。

修复代码

import { useState } from "react"

export const App = () => {
    const [records, setRecords] = useState({ data: [], errState: false })

    const addRecord = () => {
        setRecords(ps => {
            const newList = [...ps.data]
            newList.push(`This Will Be Record ${newList.length}`)
            return { ...ps, data: newList }
        })
    }

    const delRecord = (id) => {
        setRecords(ps => {
            const newList = ps.data.filter((_, index) => index !== id)
            return { ...ps, data: newList }
        })
    }

    const buildRows = () => {
        return records.data.map((r, rndx) => {
            return (
                <div key={`${r}-${rndx}`} style={{ display: "flex",marginBottom:"10px" }}>
                    <div style={{ flex: 1, paddingRight: "20px" }}><input id={`test-${rndx}`}/></div>
                    <div style={{ width: "50px" }}><button onClick={() => delRecord(rndx)}>Delete</button></div>
                </div>
            )
        })
    }

    return (
        <div style={{ width: "800px", margin: "0 auto", textAlign: "center" }}>
            {buildRows()}
            <button onClick={addRecord}>Add Record</button>
        </div>
    )
}

关键修复点

  • 添加唯一key:给每个列表项添加唯一key,让React准确识别元素,避免DOM复用错误。实际项目中建议使用后端返回的唯一ID,这里用内容+索引临时保证唯一性。
  • 优化状态更新逻辑:
    • 添加、删除操作均使用函数式更新,确保基于最新state修改,规避闭包问题。
    • 删除操作改用filter创建新数组,符合React不可变数据的原则(避免直接修改原数组)。
    • 直接将索引作为参数传递给delRecord,简化逻辑,避免DOM属性操作的潜在问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 05:15:11