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

点击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()
        }

尝试实现自动刷新时的疑问:

  1. 在页面组件中初始化tasks状态:const [tasks, setTasks] = useState([]);
    • 疑问:该页面是否是包含上述header-box的页面?是否需要新建jsx文件还是复用现有组件?
  2. 将tasks状态作为props传递给TaskButton组件:<TaskButton task={task} tasks={tasks} setTasks={setTasks} />
    • 疑问:是否需要复用现有TaskButton组件还是新建?
  3. 在markAsDone函数中更新tasks状态的逻辑是否合理?
  4. 如何确保页面组件依赖state重新渲染任务列表?

核心需求:通过state属性让页面组件重新渲染最新信息,实现点击X按钮后自动刷新任务盒子。


解决方案

逐个解答疑问

  1. 是包含.header-box的页面,直接复用现有页面组件即可,无需新建。这个页面是任务列表的根组件,所有任务相关的状态应该在这里统一维护。
  2. 复用现有TaskButton组件,仅需修改其参数接收逻辑,让它能接收触发状态更新的函数即可,无需新建组件。
  3. 原状态更新逻辑存在冗余:任务已从数据库删除,不需要标记为Complete,而是应该直接用拉取的最新任务列表更新state,避免本地状态与数据库不一致。
  4. 确保任务列表组件(如TaskList)依赖tasks props渲染,当tasks state变化时,组件会自动重新渲染。

完整实现代码

步骤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;

关键说明

  1. 单一数据源:所有任务状态由根组件统一维护,子组件仅负责展示和触发操作,避免状态分散导致的同步问题。
  2. 可靠状态更新:数据库操作完成后,直接拉取最新任务列表更新state,确保本地状态与数据库完全一致。
  3. 组件职责清晰:TaskButton仅负责渲染按钮和触发事件,状态更新逻辑集中在根组件,便于后续维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 15:45:03