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

React中执行删除操作后map渲染的表格未更新问题

问题原因
  • 核心原因是违反了React的状态不可变原则:React判断状态是否需要更新触发重渲染,靠的是对状态值的浅比较。你代码里用的splice方法会直接原地修改原数组,修改后传给setList的数组和原有状态的数组是同一个内存引用,React会认为状态没有发生变化,自然不会触发重渲染。
  • 额外逻辑错误:你执行splice操作的目标是组件内定义的普通常量trains,不是状态变量trainList,本身就没有对正确的状态源做操作。
  • 潜在隐患:按钮的id属性拿到的是字符串类型的索引,直接传入splice虽然会被JS隐式转换为数字,但显式转换类型能避免很多边界问题。
修复方法

不要直接修改原数组,基于现有状态生成一个全新的数组,再传给状态更新函数。推荐用filter方法直接过滤掉要删除的项,该方法天然返回新数组不会修改原数组,写法也更简洁。
修复后的完整代码:

function TrainPage(){
    const [trainList, setList] = useState([
        {name: "Thomas", dest: "New York", first: "05:00", freq: 30},
        {name: "Duncan", dest: "Boston", first: "06:00", freq: 45}
    ]);

    function remove(event){
        // 拿到要删除的索引,转成数字类型
        const deleteIndex = Number(event.target.id);
        // 用filter生成新数组,过滤掉索引匹配的项,不修改原数组
        const newList = trainList.filter((_, index) => index !== deleteIndex);
        setList(newList);
    }

    return(
        <div>
            <table>
                <tr>
                    <th>Train Name</th>
                    <th>Destination</th>
                    <th>Frequency</th>
                    <th>Minutes Away</th>
                    <th>Next Arrival</th>
                </tr>
                {trainList.map((train, index) => (
                    <tr key={index}>
                        <td>{train.name}</td>
                        <td>{train.dest}</td>
                        <td>{train.freq}mins</td>
                        <td></td>
                        <td></td>
                        <td>
                            <button 
                                onClick={remove} 
                                data-toggle='tooltip' 
                                data-placement='left' 
                                title='delete train' 
                                id={index}
                            >
                                x
                            </button>
                        </td>
                    </tr>
                ))}
            </table>
        </div>
    )
}

补充:列表渲染的时候建议给每一项加唯一的key属性,上面代码暂时用index兜底,如果列车数据有唯一ID(比如车次编号),用唯一ID当key比索引更稳妥,能避免列表顺序变动时的渲染异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 00:15:37