当用户单击按钮时,我试图在我的 React 应用程序的客户端显示使用 mongoose 存储的集合属性的值。
通过检索点击时的值并使用 setState 存储该值。
我的问题-- 我似乎无法设置状态并立即在单击时显示新值... 下一次单击时,显示的值是上一次单击的值。
我的后端node.js代码,用于从mongodb获取数据
app.post('/api/showengagement', async (req, res) => {
const result = await Post.findOne({url: req.body.url}, "likes");
res.send(result);
})
我的前端react.js代码用于处理onClick并显示获取的数据
handleLike(url, e){
if (e.target.innerText.toLowerCase() === "like"){
axios.post('/api/showengagement', {url: url})
.then(res => this.setState({
likeEngage: res.data.likes
}));
e.target.innerText = `This post has ${this.state.likeEngage} like(s)`
axios.post('/api/incrementlikes', {url: url});
}
else{
e.target.innerText = "Like";
axios.post('/api/decrementlikes', {url: url});
}
}
感谢您的帮助!
最佳答案
您看到了错误的值,因为您在 axios.post
完成之前设置了 e.target.innerText
。您可以将该代码移动到回调中以获得所需的操作顺序,如下所示:
handleLike = (url, e) => {
if (e.target.innerText.toLowerCase() === "like"){
axios.post('/api/showengagement', {url: url})
.then(res => {
e.target.innerText = `This post has ${res.data.likes} like(s)`
});
axios.post('/api/incrementlikes', {url: url});
}
else{
e.target.innerText = "Like";
axios.post('/api/decrementlikes', {url: url});
}
}
通过这种方式,您甚至不需要将值存储在状态
中。如果代码中的其他地方需要的话,您仍然可以这样做。
您对 innerText
的设置发生在值返回之前的原因是 axios.post
是异步的,并且在操作完成之前返回并且您的函数继续执行下一行(将文本设置为旧值)。当 post
完成并且您的回调函数被调用时,新值会稍后出现。
更好:避免使用innerText - 使用render()
执行此操作的另一种方法是让 render()
函数负责使用 state
变量将值写入适当的位置。当您调用 this.setState() 时,它会导致组件再次呈现,您将看到该值出现。这是一个显示它的工作 React 类:
import React from "react";
let likes = [];
let urls = ["url1", "url2"];
class Sample extends React.Component {
constructor(props) {
super(props);
this.state = { likeEngages: [] }; // initialize the array of likeEngages
}
// fake implementation of 'post' instead of axios.post
post = (url, body) => {
if (!likes[body.id]) likes[body.id] = 1;
if (url === "/api/showengagement") {
return Promise.resolve({ data: { likes: likes[body.id] } });
} else {
likes[body.id]++; // increment Likes for given id
return Promise.resolve();
}
};
handleLike = (url, e) => {
const id = e.target.id;
this.post("/api/showengagement", { url, id }).then(res => {
const engages = this.state.likeEngages;
engages[id] = res.data.likes; // set the likes count in the state
this.setState({ likeEngages: engages });
});
this.post("/api/incrementlikes", { url, id });
};
showLikes = id => {
if (this.state.likeEngages[id])
return (
<span>
{" This post has " + this.state.likeEngages[id] + " like(s)"}
</span>
);
return " No likes yet";
};
render() {
return (
<div>
<ul>
<li>
<button id="id1" onClick={e => this.handleLike(urls[0], e)}>
Like1
</button>
{this.showLikes("id1")}
</li>
<li>
<button id="id2" onClick={e => this.handleLike(urls[1], e)}>
Like2
</button>
{this.showLikes("id2")}
</li>
</ul>
</div>
);
}
}
export default Sample;
关于javascript - 从数据库获取值并在 React 前端显示的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58784383/