javascript - 从数据库获取值并在 React 前端显示的最佳方法

标签 javascript node.js reactjs axios

当用户单击按钮时,我试图在我的 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/

相关文章:

javascript - 在javascript中合并对象

mysql - 从 App Engine 连接到 Google Cloud SQL 时出现 ENOENT

javascript - 如何在 react-router Route 中从 onChange 调用 dispatch?

reactjs - Redux:区分reducers中的对象

javascript - 在多个选择框 JQuery 上动态生成 URL

javascript - 使用 Angular 根据单独选择的选项显示 HTML 选项

javascript - 无法加载转译器

javascript - JavaScript shell 和 node.js 的区别

javascript - 如何处理同一数组中多个对象的 onClick

javascript - 如何进行简单的星级评定?