点击X按钮后如何更新React任务盒子并触发组件重渲染?
问题:点击标记完成按钮后自动刷新任务盒子
点击标记任务为完成的红色X按钮后,任务会从数据库中删除,需要自动刷新页面中的任务盒子:
<div className="container team-member-tasks"> <header className="header-box"> <h1>Team Member Tasks</h1>
当前的TaskButton组件及markAsDone函数实现如下:
const TaskButton = task => { if (task.task.status !== 'Complete') { return ( <td> <h3 onClick={() => markAsDone(task)} style={{ color: 'red' }} data-toggle="tooltip" data-placement="top" title="MARK AS DONE. MARKING THIS AS DONE WOULD REMOVE THE TASK PERMANENTLY." className="markAsDoneButton" > X </h3> </td> ) } else { return <td></td> } } const markAsDone = async task => { task.task.status = 'Complete' const updatedTask = { taskName: task.task.taskName, priority: task.task.priority, resources: task.task.resources, isAssigned: task.task.isAssigned, status: task.task.status, hoursBest: parseFloat(task.task.hoursBest), hoursWorst: parseFloat(task.task.hoursWorst), hoursMost: parseFloat(task.task.hoursMost), estimatedHours: parseFloat(task.task.hoursEstimate), startedDatetime: task.task.startedDate, dueDatetime: task.task.dueDate, links: task.task.links, whyInfo: task.task.whyInfo, intentInfo: task.task.intentInfo, endstateInfo: task.task.endstateInfo, classification: task.task.classification, } await updateTask(String(task.task._id), updatedTask) await deleteSelectedTask(task.task._id, task.task.mother) await dispatch(getAllUserProfile()) await fetchAllTasks() }
尝试实现自动刷新时的疑问:
- 在页面组件中初始化tasks状态:
const [tasks, setTasks] = useState([]);- 疑问:该页面是否是包含上述header-box的页面?是否需要新建jsx文件还是复用现有组件?
- 将tasks状态作为props传递给TaskButton组件:
<TaskButton task={task} tasks={tasks} setTasks={setTasks} />- 疑问:是否需要复用现有TaskButton组件还是新建?
- 在markAsDone函数中更新tasks状态的逻辑是否合理?
- 如何确保页面组件依赖state重新渲染任务列表?
核心需求:通过state属性让页面组件重新渲染最新信息,实现点击X按钮后自动刷新任务盒子。
解决方案
逐个解答疑问
- 是包含
.header-box的页面,直接复用现有页面组件即可,无需新建。这个页面是任务列表的根组件,所有任务相关的状态应该在这里统一维护。 - 复用现有TaskButton组件,仅需修改其参数接收逻辑,让它能接收触发状态更新的函数即可,无需新建组件。
- 原状态更新逻辑存在冗余:任务已从数据库删除,不需要标记为
Complete,而是应该直接用拉取的最新任务列表更新state,避免本地状态与数据库不一致。 - 确保任务列表组件(如
TaskList)依赖tasksprops渲染,当tasksstate变化时,组件会自动重新渲染。
完整实现代码
步骤1:在根组件(含header-box的页面)维护任务状态
import { useState, useEffect } from 'react'; const TeamMemberTasksPage = () => { const [tasks, setTasks] = useState([]); // 页面加载时拉取初始任务列表 useEffect(() => { fetchAllTasks().then(fetchedTasks => setTasks(fetchedTasks)); }, []); // 定义标记任务完成的函数,放在根组件统一处理状态更新 const markAsDone = async task => { try { task.task.status = 'Complete'; const updatedTask = { taskName: task.task.taskName, priority: task.task.priority, resources: task.task.resources, isAssigned: task.task.isAssigned, status: task.task.status, hoursBest: parseFloat(task.task.hoursBest), hoursWorst: parseFloat(task.task.hoursWorst), hoursMost: parseFloat(task.task.hoursMost), estimatedHours: parseFloat(task.task.hoursEstimate), startedDatetime: task.task.startedDate, dueDatetime: task.task.dueDate, links: task.task.links, whyInfo: task.task.whyInfo, intentInfo: task.task.intentInfo, endstateInfo: task.task.endstateInfo, classification: task.task.classification, }; // 执行数据库操作 await updateTask(String(task.task._id), updatedTask); await deleteSelectedTask(task.task._id, task.task.mother); await dispatch(getAllUserProfile()); // 拉取最新任务列表,更新state触发重新渲染 const latestTasks = await fetchAllTasks(); setTasks(latestTasks); } catch (error) { console.error('标记任务完成失败:', error); } }; return ( <div className="container team-member-tasks"> <header className="header-box"> <h1>Team Member Tasks</h1> </header> {/* 传递tasks和markAsDone给任务列表组件 */} <TaskList tasks={tasks} markAsDone={markAsDone} /> </div> ); }; export default TeamMemberTasksPage;
步骤2:修改TaskButton组件,接收markAsDone作为props
const TaskButton = ({ task, markAsDone }) => { if (task.task.status !== 'Complete') { return ( <td> <h3 onClick={() => markAsDone(task)} style={{ color: 'red', cursor: 'pointer' }} data-toggle="tooltip" data-placement="top" title="MARK AS DONE. MARKING THIS AS DONE WOULD REMOVE THE TASK PERMANENTLY." className="markAsDoneButton" > X </h3> </td> ); } else { return <td></td>; } }; export default TaskButton;
步骤3:在TaskList组件中渲染任务及按钮
const TaskList = ({ tasks, markAsDone }) => { return ( <table> {/* 根据你的实际布局调整容器类型 */} <tbody> {tasks.map(taskItem => ( <tr key={taskItem.task._id}> {/* 渲染任务其他信息列 */} <td>{taskItem.task.taskName}</td> <td>{taskItem.task.priority}</td> {/* 渲染标记完成按钮 */} <TaskButton task={taskItem} markAsDone={markAsDone} /> </tr> ))} </tbody> </table> ); }; export default TaskList;
关键说明
- 单一数据源:所有任务状态由根组件统一维护,子组件仅负责展示和触发操作,避免状态分散导致的同步问题。
- 可靠状态更新:数据库操作完成后,直接拉取最新任务列表更新state,确保本地状态与数据库完全一致。
- 组件职责清晰:TaskButton仅负责渲染按钮和触发事件,状态更新逻辑集中在根组件,便于后续维护。
内容的提问来源于stack exchange,提问作者Oliveira
相关产品推荐
相关产品推荐

