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

React点击删除数组元素仅顶部生效、Filter方法无效果问题求助

问题原因

你的代码存在3处核心错误导致删除功能异常:

  • Array.map参数命名混淆:map的第一个参数为当前遍历的元素对象,第二个才是索引值,你代码中todos.map((key, value) =>)的命名完全颠倒,导致后续传参错误
  • 删除逻辑入参不匹配:点击删除按钮时你给deleteTodo传递的是完整的todo对象,而非id或索引:
    • 采用filter方案时,你用数字id和todo对象做全等判断,永远返回true,所以不会过滤任何元素,数组长度无变化
    • 采用splice方案时,splice接收到todo对象后会尝试转数字,得到的结果为NaN,splice默认将无效下标当做0处理,因此永远删除数组第一个元素
  • 状态日志逻辑错误:React的setTodos是异步更新,你在调用后直接打印todos.length拿到的是更新前的旧值,不能作为删除是否生效的判断依据

修复方案(推荐基于ID删除,稳定性更高)

import { useEffect, useState } from "react";

const Task = () => {
    const [todos, setTodos] = useState([]);

    useEffect(() => {
        fetch('http://jsonplaceholder.typicode.com/todos')
            .then(res => res.json())
            .then(data => {
                setTodos(data)
            })
    }, []);

    // 基于ID删除
    const deleteTodo = (id) => {
        const newTodo = todos.filter(todo => todo.id !== id);
        setTodos(newTodo);
        // 要查看更新后长度请在setTodos的回调或者useEffect中监听todos变化
    }

    return (
        <div className='container'>
            <table className='table'>
                <tbody>
                    {/* 修正map参数命名 */}
                    {todos.map((todo, index) => (
                        <tr key={todo.id}>
                            <td>{todo.id}</td>
                            <td>{todo.title}</td>
                            <td>{`${todo.completed}`}</td>
                            <td>
                                {/* 传递当前todo的id到删除函数 */}
                                <button className='btn btn-danger ' onClick={() => deleteTodo(todo.id)}> Delete </button>
                            </td>
                        </tr>
                    ))}
                </tbody>
            </table>
            <button className='btn btn-primary'>Add Task</button>
        </div>
    );
}
export default Task;

如果你要使用索引删除的方案可参考如下修改

// 基于索引删除的函数
const deleteTodo = (index) => {
    const temp = [...todos];
    temp.splice(index, 1);
    setTodos(temp);
}

// 调用处传索引即可
<button className='btn btn-danger ' onClick={() => deleteTodo(index)}> Delete </button>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 11:24:01