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

MERN栈提交任务后无需刷新重新渲染页面的实现方案咨询

解决MERN栈任务创建后页面自动刷新问题

问题背景

管理员通过弹窗表单创建任务,数据已成功存入数据库,但客户端需切换页面或手动刷新才能看到新任务,需实现提交后自动更新页面内容。

解决方案

方案1:创建成功后重新拉取完整任务列表

核心逻辑:在弹窗提交任务成功后,通知父组件重新调用数据接口,获取最新的任务列表。

修改步骤

  1. 在Task组件中定义数据刷新的回调函数,并传递给Popup组件
  2. 在Popup组件的提交成功逻辑里调用该回调函数

修改后Task组件代码:

function Task() {
  const [userData, setUserData] = useState([]);
  const [openPopup, setOpenPopup] = useState(false);

  const getData = async () => {
    const res = await fetch("/createtask", {
      method: "GET",
      headers: {
        "content-type": "application/json",
      },
    });

    const data = await res.json();
    if (res.status === 404 || !data) {
      alert("error");
      console.log("error");
    } else {
      setUserData(data);
    }
  };

  useEffect(() => {
    getData();
  }, []);

  // 新增:触发数据刷新的回调函数
  const refreshTaskList = () => {
    getData();
  };

  return (
    <>
      <Sidebar/>
      <div className="tskms_task_mid">
        <div className="tskms_task_mid-top">
          <h2>Tasks</h2>
          <Button
            id="createtask"
            variant="contained"
            onClick={() => setOpenPopup(true)}
          >
            Create Task
          </Button>
        </div>
        {/* 传递刷新回调给Popup组件 */}
        <Popup 
          openPopup={openPopup} 
          setOpenPopup={setOpenPopup} 
          onTaskCreated={refreshTaskList} 
        />
        {/* 此处需补充渲染userData的列表代码 */}
      </div>
    </>
  );
}

修改后Popup组件代码:

function Popup(props) {
  // 接收父组件传递的刷新回调
  const { openPopup, setOpenPopup, onTaskCreated } = props;
  const [employeeName, setEmployeeName] = useState({
    taskName: "",
    assignTo: "",
    startedOn: new Date(),
    dueDate: new Date(),
    taskDescription: "",
    requiredFiles: "",
  });

  const clgdata = (e) => {
    const { name, value } = e.target;
    setEmployeeName((newData) => ({ ...newData, [name]: value }));
  };

  const changeStartDate = (newValue) => {
    setEmployeeName((prev) => ({ ...prev, startedOn: newValue }));
  };

  const changeDueDate = (newValue) => {
    setEmployeeName((prev) => ({ ...prev, dueDate: newValue }));
  };

  const createTask = async (e) => {
    e.preventDefault();
    const { taskName, assignTo, startedOn, dueDate, taskDescription, requiredFiles } = employeeName;
    const res = await fetch("http://localhost:3001/createtask", {
      method: "POST",
      headers: {
        "content-type": "application/json",
      },
      body: JSON.stringify({ taskName, assignTo, startedOn, dueDate, taskDescription, requiredFiles }),
    });
    const data = await res.json();
    if (res.status === 404 || !data) {
      alert("Please Complete the Empty Fields");
    } else {
      alert(`Task has been assigned to the employee`);
      setOpenPopup(false);
      // 调用父组件的刷新函数
      onTaskCreated();
      // 移除不必要的页面跳转
      // history("/task");
    }
  };

  return (
    <>
      <Dialog open={openPopup}>
        <DialogTitle>
          <div className="title">
            <ArrowBackIcon className="leftArrow" onClick={() => setOpenPopup(false)}>
              close
            </ArrowBackIcon>
            <h3>Create a task</h3>
          </div>
        </DialogTitle>
        <DialogContent>
          <div className="form">
            <TextField
              className="form-btn"
              name="taskName"
              type="text"
              id="outlined-basic"
              label="Task Title"
              variant="outlined"
              onChange={clgdata}
              value={employeeName.taskName}
            />
            <TextField
              sx={{ mb: 1 }}
              name="assignTo"
              type="text"
              onChange={clgdata}
              value={employeeName.assignTo}
              className="form-btn"
              id="outlined-basic"
              label="Select an Employee"
            />
            <LocalizationProvider dateAdapter={AdapterDateFns}>
              <Stack spacing={1}>
                <DatePicker
                  sx={{ m: 4 }}
                  name="startedOn"
                  minDate={new Date()}
                  className="form-btn startedOn"
                  label="Started On"
                  type="date"
                  value={employeeName.startedOn}
                  onChange={changeStartDate}
                  renderInput={(params) => <TextField {...params} />}
                />
                <DatePicker
                  className="startedOff"
                  minDate={new Date()}
                  id="dueDate"
                  name="dueDate"
                  label="Due Date"
                  value={employeeName.dueDate}
                  onChange={changeDueDate}
                  renderInput={(params) => <TextField {...params} />}
                />
                <TextField
                  sx={{ mb: 1}}
                  className="form-btn"
                  id="outlined-basic"
                  label="Task Description"
                  variant="outlined"
                  name="taskDescription"
                  type="text"
                  onChange={clgdata}
                  value={employeeName.taskDescription}
                />
              </Stack>
            </LocalizationProvider>
            <TextField
              sx={{ mb: 1 }}
              className="form-btn"
              id="outlined-basic"
              label="Required Files"
              variant="outlined"
              name="requiredFiles"
              type="text"
              onChange={clgdata}
              value={employeeName.requiredFiles}
            />
          </div>
        </DialogContent>
        <DialogActions>
          <Button onClick={createTask}>Submit</Button>
        </DialogActions>
      </Dialog>
    </>
  );
}

export default Popup;

方案2:直接添加新任务到现有列表(性能优化)

如果后端在创建任务后返回新任务的完整数据,可以直接将其添加到现有列表,避免重复请求接口:

修改Popup组件的createTask函数

const createTask = async (e) => {
  e.preventDefault();
  const { taskName, assignTo, startedOn, dueDate, taskDescription, requiredFiles } = employeeName;
  const res = await fetch("http://localhost:3001/createtask", {
    method: "POST",
    headers: {
      "content-type": "application/json",
    },
    body: JSON.stringify({ taskName, assignTo, startedOn, dueDate, taskDescription, requiredFiles }),
  });
  // 假设后端返回新创建的任务对象
  const newTask = await res.json();
  if (res.status === 404 || !newTask) {
    alert("Please Complete the Empty Fields");
  } else {
    alert(`Task has been assigned to the employee`);
    setOpenPopup(false);
    // 传递新任务数据给父组件
    onTaskCreated(newTask);
  }
};

修改Task组件的refreshTaskList函数

const refreshTaskList = (newTask) => {
  // 将新任务追加到现有列表
  setUserData(prev => [...prev, newTask]);
};

注意事项

  • 方案1兼容性强,无需修改后端逻辑;方案2需要后端配合返回新任务数据,性能更优
  • 确保后端POST接口返回正确的状态码和数据格式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 19:48:17