MERN栈提交任务后无需刷新重新渲染页面的实现方案咨询
解决MERN栈任务创建后页面自动刷新问题
问题背景
管理员通过弹窗表单创建任务,数据已成功存入数据库,但客户端需切换页面或手动刷新才能看到新任务,需实现提交后自动更新页面内容。
解决方案
方案1:创建成功后重新拉取完整任务列表
核心逻辑:在弹窗提交任务成功后,通知父组件重新调用数据接口,获取最新的任务列表。
修改步骤
- 在
Task组件中定义数据刷新的回调函数,并传递给Popup组件 - 在
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
相关产品推荐
相关产品推荐

