MERN栈项目Delete按钮无法删除记录问题排查
MERN栈删除记录不生效修复方案
你的代码一共存在4处前后端逻辑错误,逐一修复即可正常工作:
- 前端
setState字段名拼写错误:初始化的列表state字段为records,删除逻辑里误写为record,更新操作没有命中渲染依赖的数据源 - 前端删除回调传递错误:列表渲染时传入子组件的
deleteRecord只返回了函数引用,既没有执行也没有透传记录id参数 - 删除按钮默认行为未拦截:
<a>标签设置了href="/",点击时会触发页面跳转刷新,重置前端state为接口拉取的全量数据 - 后端删除接口逻辑错误:接口路径缺少
/record前缀和前端请求不匹配,同时查询条件误取req.body.id,实际id存在路径参数中,且MongoDB主键字段为_id而非id,根本匹配不到待删除记录
前端修复(recordList.js)
- 修正Record组件内删除按钮的点击事件,阻止默认跳转行为
- 修正列表渲染时的回调传参,正确透传删除方法
- 修正删除请求路径,等待接口返回成功后再更新state,修正state字段名拼写
对应修正后代码:
import React, { Component } from "react"; import axios from 'axios'; import { Link } from "react-router-dom"; const Record = (props) => ( <tr> <td>{props.record.person_name}</td> <td>{props.record.person_position}</td> <td>{props.record.person_level}</td> <td> <Link to={"/edit/" + props.record._id}>Edit</Link> | <a href="/" onClick={(e) => { // 阻止a标签默认跳转 e.preventDefault(); props.deleteRecord(props.record._id); }} > Delete </a> </td> </tr> ); export default class RecordList extends Component { constructor(props) { super(props); this.deleteRecord = this.deleteRecord.bind(this); this.state = { records: [] }; } componentDidMount() { axios .get("https://julio-mern-app.herokuapp.com/record/") .then((response) => { this.setState({ records: response.data }); }) .catch(function (error) { console.log(error); }); } deleteRecord(id) { axios // 补全接口路径前缀 .delete("https://julio-mern-app.herokuapp.com/record/" + id).then((response) => { console.log(response.data); // 接口请求成功后再更新state,修正state字段名为records this.setState({ records: this.state.records.filter((el) => el._id !== id), }); }); } recordList() { return this.state.records.map((currentrecord) => { return ( <Record record={currentrecord} // 正确传递删除方法 deleteRecord={this.deleteRecord} key={currentrecord._id} /> ); }); } render() { return ( <div> <h2> JulioCorp Software </h2> <h3>Click 'Create Record' above to add your name if you are a...</h3> <h3>Amazing Individual!</h3> <h6>Make page wider if you do not see "Create Record" button. </h6> <table className="table table-striped" style={{ marginTop: 20 }}> <thead> <tr> <th>Name</th> <th>Amazing Quality</th> <th>Level</th> <th>Action</th> </tr> </thead> <tbody>{this.recordList()}</tbody> </table> </div> ); } }
后端修复(record.js)
- 修正删除接口的查询逻辑,从路径参数取id,匹配MongoDB的
_id字段(需要引入ObjectId做类型转换) - 接口执行完成后返回响应给前端
- 额外注意:你现有更新接口也存在同样的id匹配问题,可同步修复
对应修正后删除接口代码:
// 顶部引入ObjectId,做id类型转换 const ObjectId = require('mongodb').ObjectId; // ... 其他原有路由保持不变 // 修正后的删除接口 recordRoutes.route("/record/:id").delete((req, res) => { let db_connect = dbo.getDb("employees"); // 从路径参数取id,转成ObjectId类型匹配MongoDB的_id字段 let myquery = { _id: new ObjectId(req.params.id) }; db_connect .collection("individuals") .deleteOne(myquery, function (err, obj) { if (err) throw err; console.log("1 document deleted"); // 返回响应给前端 res.json({ status: "delete success", data: obj }); }); });
注:如果你的服务启动文件里给recordRoutes挂载的前缀不是
/record,需要对应调整删除接口的路径,保证和前端请求地址一致即可。
内容的提问来源于stack exchange,提问作者codereyes
相关产品推荐
相关产品推荐

