我将按照教程构建一个完整的React + NodeJS待办事项列表应用程序。我创建了一个React Task组件,该组件显示特定任务的信息并提供更新/删除按钮。由于某些原因,无论我选择更改哪个任务,我的React updateTask和deleteTask函数都会更新/删除最旧的任务。
我在React中使用 update 状态变量来切换更新表单。 另外,在 updateTask 函数中记录 res 会返回成功和要更新的正确ID。但是,这不是实际更新的ID。
反应任务组件(Task.js):
import React, { Component } from "react";
import axios from "axios";
class Task extends Component {
constructor({_id, title, due, desc}) {
super();
this.state = {
id: _id,
title: title,
due: due,
desc: desc,
update: false
}
this.updateTask = this.updateTask.bind(this);
this.deleteTask = this.deleteTask.bind(this);
}
updateTask = () => {
const {id, title, due, desc} = this.state;
axios.post("/tasks/update", {
id: id,
update: {
title: title,
due: due,
desc: desc
}
})
.then(
res => {
console.log(res);
console.log(res.data);
}
);
};
deleteTask = () => {
const {id} = this.state;
axios.delete("/tasks/delete", {
id: id
});
};
render() {
const {id, title, due, desc, update} = this.state;
return (
<div className="task">
<div>{id}</div>
{update ?
<div className="task-update">
<input
type="text"
onChange={e => this.setState({ title: e.target.value })}
value={title}
/>
<input
type="date"
onChange={e => this.setState({ due: e.target.value })}
value={!due ? "" : due.slice(0,10)}
/>
<textarea
onChange={e => this.setState({ desc: e.target.value })}
value={!desc ? "" : desc}
/>
<button onClick={this.updateTask}>
Update Task
</button>
</div>
:
<div className="task-show">
<div className="task-info">
<div>{title}</div>
<div>{!due ? "no date" : due.slice(0,10)}</div>
<p>{desc}</p>
</div>
<div className="task-btns">
<button
className="task-edit"
onClick={e => this.setState({update: true})}
>
</button>
<button
className="task-done"
onClick={() => this.doneTask()}
></button>
<button
className="task-del"
onClick={this.deleteTask}
>
</button>
</div>
</div>
}
</div>
);
}
}
export default Task;
NodeJS任务控制器:
var express = require('express');
var router = express.Router();
const Task = require("../models/task");
const Data = require("../models/data");
router.get("/all", (req, res) => {
Task.find((err, tasks) => {
if (err) return res.json({ success: false, error: err });
return res.json({ success: true, tasks: tasks });
});
});
router.post("/update", (req, res) => {
const { id, update } = req.body;
Task.findOneAndUpdate(id, update, err => {
if (err) return res.json({ success: false, error: err });
return res.json({ success: true, id: id});
});
});
router.delete("/delete", (req, res) => {
const { id } = req.body;
Task.findOneAndDelete(id, err => {
if (err) return res.send(err);
return res.json({ success: true });
});
});
router.post("/create", (req, res) => {
let task = new Task();
const {title, due, desc} = req.body;
if (!title) {
return res.json({
success: false,
error: "INVALID INPUTS"
});
}
task.title = title;
task.due = due;
task.desc = desc;
task.save(err => {
if (err) return res.json({ success: false, error: err });
return res.json({ success: true });
});
});
module.exports = router;
谢谢您的帮助!
答案 0 :(得分:1)
您应该使用Task.findOneAndUpdate({_id: id}, ...)
。如果您不使用{_id: id}
之类的有效查询,就我所知,它总是返回第一个对象。
猫鼬findOneAndUpdate
接受query
作为第一个参数。更多信息here。
答案 1 :(得分:0)
尝试在删除任务时单击this.state.id,或将e.target.value传递给delete函数,然后将ID分配给api调用