MERN栈外出审批系统API PATCH后端实现及状态不保留问题解决
外出审批系统PATCH请求状态不持久化问题解决
问题概述
使用MERN栈开发外出审批系统时,前端调用审批函数将leaveStatus设置为"Approved"后,页面刷新状态就会恢复原样,但通过Postman发送PATCH请求能正常保存状态。
相关代码片段:
Mongoose Schema中leaveStatus定义
leaveStatus : { type : String, default : 'Not Approved', enum : [ 'Approved', 'Not Approved' ] }
前端审批函数
const approveOuting = async () => { const response = await fetch('api/outings/' + outing._id, { method: 'PATCH' }) if (response.ok) { const json = await response.json() var updatedJson = {...json, leaveStatus : "Approved"} dispatch({type: 'PATCH_OUTING', payload: updatedJson}) } }
Reducer处理逻辑
case 'PATCH_OUTING' : // 找到要更新的外出申请索引 const outingIndex = state.outings.findIndex((outing) => outing._id === action.payload._id); // 复制数组并更新对应项 const updatedOutings = [...state.outings]; updatedOutings[outingIndex] = action.payload; return { outings: updatedOutings };
问题原因
前端的PATCH请求没有向后端发送任何更新数据,只是在拿到后端返回的原始数据后,手动在前端修改了leaveStatus并更新了Redux状态。这种修改只存在于前端内存中,并没有同步到数据库。刷新页面后,前端重新从数据库拉取数据,自然会回到原始状态。而Postman请求时你肯定在请求体中携带了leaveStatus的更新值,所以后端能正确更新数据库。
解决方案
1. 修改前端请求,传递更新数据给后端
更新approveOuting函数,添加请求头和请求体,把要修改的leaveStatus传给后端:
const approveOuting = async () => { const response = await fetch(`api/outings/${outing._id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' // 告诉后端请求体是JSON格式 }, body: JSON.stringify({ leaveStatus: "Approved" }) // 发送更新字段 }) if (response.ok) { const updatedJson = await response.json() dispatch({type: 'PATCH_OUTING', payload: updatedJson}) } }
2. 确保后端PATCH接口正确处理更新
如果还没实现后端的PATCH接口,或者接口逻辑有问题,参考以下Express+Mongoose示例:
// 路由文件示例(假设是routes/outings.js) const express = require('express'); const router = express.Router(); const Outing = require('../models/Outing'); // 你的Mongoose模型 router.patch('/outings/:id', async (req, res) => { try { // 根据ID更新,{new: true}返回更新后的文档,runValidators确保枚举验证生效 const updatedOuting = await Outing.findByIdAndUpdate( req.params.id, { leaveStatus: req.body.leaveStatus }, { new: true, runValidators: true } ); if (!updatedOuting) { return res.status(404).json({ message: '外出申请不存在' }); } res.json(updatedOuting); // 返回更新后的文档给前端 } catch (error) { res.status(400).json({ message: error.message }); } }); module.exports = router;
3. 优化前端状态更新
现在后端会返回更新后的完整文档,前端无需手动修改leaveStatus,直接用后端返回的数据更新Redux状态即可,避免前后端数据不一致。
内容的提问来源于stack exchange,提问作者thePrnvBot
相关产品推荐
相关产品推荐

