React发起删除fetch请求后UI未刷新,使用useEffect报错如何解决
问题核心原因
你的任务列表数据存储在App组件的tasks状态中,调用DELETE接口仅同步了后端数据,前端的tasks状态没有对应更新,所以UI不会自动刷新。
你之前在deleteTaskHandler中调用useEffect报错,是因为违反了React Hook的使用规则:Hook只能在组件函数的最顶层调用,不能在事件回调、循环、条件判断等内部调用。
具体解决方案(两步即可实现)
1. 向下传递列表刷新方法
你App组件中已经定义了拉取最新任务列表的fetchTasksHandler方法,只需要把这个方法逐层传递到Task组件即可:
- 首先修改
App.js的渲染逻辑,给TaskList传递刷新方法:
// App.js return部分修改 return ( <React.Fragment> <TaskList taskData={tasks} onChangeTaskURL={changeTaskURL} // 新增:传递刷新列表的方法 onRefreshTasks={() => fetchTasksHandler(taskURL)} ></TaskList> <NewTask></NewTask> </React.Fragment> );
- 然后修改
TaskList.js,接收刷新方法并传递给Task组件:
// TaskList.js 先修改组件参数接收props const TaskList = (props) => { // ...原有逻辑不变 // 修改渲染Task的部分,给全量展示的分支加onRefresh prop if (taskView != 'all') { taskList = props.taskData.map((task) => ( <Task key={task.id} content={task.content} dateCreation={task.dateCreation} isCompleted={task.isCompleted} isAllView={false} /> )); } else { taskList = props.taskData.map((task) => ( <Task key={task.id} id={task.id} content={task.content} dateCreation={task.dateCreation} isCompleted={task.isCompleted} isAllView={true} // 新增:传递刷新方法 onRefresh={props.onRefreshTasks} /> )); } // ...原有逻辑不变 }
2. 删除成功后调用刷新方法
修改Task.js的deleteTaskHandler,在接口请求成功后调用传入的刷新方法:
const deleteTaskHandler = async () => { try { const key = props.id const response = await fetch('http://localhost:5050/delete-task/' + key, { method: 'DELETE' }); if (!response.ok) { throw new Error('Something went wrong!'); }; const data = await response.json(); console.log(data); // 新增:调用刷新方法拉取最新列表,更新状态触发UI刷新 props.onRefresh?.(); } catch (error) { console.log(error); } };
可选优化方案(无需额外发请求)
如果不想每次删除后都发起新的请求拉列表,也可以直接在前端修改状态:
- 在App组件中定义删除任务的方法,通过props逐层传递到Task组件
- 删除成功后调用该方法,直接过滤掉
tasks中对应id的条目即可,性能比重新拉取列表更好
另外你的updateTaskHandler修改完成状态后也存在同样的UI不刷新问题,用同样的逻辑,修改成功后调用刷新方法即可解决。
内容的提问来源于stack exchange,提问作者Adrian Leal
相关产品推荐
相关产品推荐

