React删除数组数据后页面未重新渲染更新列表问题求解
问题根源
你遇到的现象有两个核心错误:
- 你直接使用
splice方法原地修改了useState返回的todos数组,React的状态是不可变的,原地修改不会触发状态更新,同时你也没有调用setTodos传入修改后的新数组,React感知不到数据变化,自然不会重新渲染列表。 - 你在删除按钮的点击事件里给
deleteTodo传的是todo的id值,并不是对应元素在数组里的下标,直接把id当成索引传入splice根本匹配不到要删除的正确条目。
修正后完整代码
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) }) }, []); // 参数接收todo的id const deleteTodo = (id) => { // 用filter生成新数组,过滤掉要删除的id对应条目,不会修改原数组 const newTodos = todos.filter(todo => todo.id !== id); // 调用setTodos更新状态,触发重渲染 setTodos(newTodos); console.log(`newLength : ${newTodos.length}`); } return ( <div className='container'> <table className='table'> <tbody> {/* 直接用遍历得到的todo对象取值,逻辑更清晰 */} {todos.map((todo) => ( <tr key={todo.id}> <td>{todo.id}</td> <td>{todo.title}</td> <td>{`${todo.completed}`}</td> <td> <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;
主要改动说明
- 删除逻辑改用
filter方法生成新数组,避免原地修改原状态,符合React的不可变数据原则 - 删除操作完成后调用
setTodos传入新的数组,触发组件重渲染 - 简化了map遍历的取值逻辑,避免通过索引访问数组容易出错的问题
- 修正了JSX中
class属性为className,符合React语法规范
内容的提问来源于stack exchange,提问作者coolhack7
相关产品推荐
相关产品推荐

