使用Ajax调用后React组件状态发生变化,但未重新渲染组件

8

在这部分中,用户可以对帖子发表评论。在服务器端检查并接收数据后,我尝试更改this.state.comments的值,然后完成。但问题是,它没有改变组件上的评论部分。 我已经阅读了有关重新渲染的先前问题,请不要标记为重复。以下是代码:

$.post("requests.php", {
    requestKey: 'newComment',
    commenterUser: commenterUser,
    commenterEmail: commenterEmail,
    theComment: theComment,
    pnum: pnum}, function(data, status, xhr){
      if(status == 'success'){
        if(data == 'commented'){
          this.setState({
            comments: data
          })
        }else{

        }
      }
    });

收到的数据是与帖子相关的所有评论,评论部分是显示所有评论的地方。

2
在这里不应该使用this.setState,因为this将是未定义的,您应该使用箭头函数或在post之前保存此值-> var that = this;,然后在回调中使用that.setState - Olivier Boissé
@Deepak 但是我已经写了 onSubmit={this.submitComment.bind(this)} 并且 state.comments 的值确实会改变。 :( - sinawic
这是函数作用域的,即使你使用this绑定了当前函数,你仍然有另一个函数在submitComment内部。要么将内部函数更改为箭头函数,要么采用@OlivierBoissé的解决方案来解决问题。 - Brijesh Bhakta
3个回答

5

您也可以使用箭头函数而不是手动绑定。

this.setState不起作用,因为在使用普通函数时它存在范围问题。

将其更改为箭头函数。 请检查下面的代码

   $.post("requests.php", {
        requestKey: 'newComment',
        commenterUser: commenterUser,
        commenterEmail: commenterEmail,
        theComment: theComment,
            pnum: pnum}, (data, status, xhr) => {
                if(status == 'success'){
                    if(data == 'commented'){
                        this.setState({
                            comments: data
                        })
                    }else{

              }
           }
       });

编辑:

如果您想避免作用域问题,可以使用箭头函数。当您使用箭头函数时,您不需要在构造函数中手动绑定函数。

 submitComment = () => {

 }

如果你使用普通函数并在该函数中使用状态或属性,则需要手动将当前对象引用到本地变量中,如下所示:

 let that = this;
 that.setState({
     name: “update”
 });

如果有任何拼写错误,对不起。我在手机上回答。


1
谢谢,但如果我使用 onSubmit={this.submitComment.bind(this)} 呢? - sinawic
更新了我的帖子以回答你的问题。请查看答案。 - Hemadri Dasari
1
谢谢,现在它运行得很好。感谢您的时间 :) - sinawic

2
let _this = this;
$.post("requests.php", {
  requestKey: 'newComment',
  commenterUser: commenterUser,
  commenterEmail: commenterEmail,
  theComment: theComment,
  pnum: pnum
}, function(data, status, xhr){
    if  (status == 'success'){
       if(data == 'commented'){
          _this.setState({ comments: data })
       } else{

       }
    }
});

我认为问题出在你对this的作用域理解上, 在javascript中this总是处于词法上下文中。


谢谢,但如果我使用 onSubmit={this.submitComment.bind(this)} 呢? - sinawic
需要绑定的是回调函数。 - Axnyff

2

您遇到了作用域问题。

让我们看一个例子:

function foo() {
    this.bar = 'lorem';
    this.ipsum = function() {
        console.log(this.bar);
    };
}

如果您调用ipsum,它会记录undefined,因为那里的this指的是ipsum function。让我们考虑这个例子:
function foo() {
    this.bar = 'lorem';
    var that = this;
    this.ipsum = function() {
        console.log(that.bar);
    };
}

在这种情况下,that 存储了外部 this 的值,因此如果调用 ipsum'lorem' 将被记录。让我们看一个箭头函数的例子:
function foo() {
    this.bar = 'lorem';
    this.ipsum = () => {
        console.log(this.bar);
    };
}

在这种情况下,如果你调用 ipsum'lorem' 会被写入控制台。
你也可以使用 bind 来达到同样的目的。
让我们在你的示例中使用箭头函数:
$.post("requests.php", {
    requestKey: 'newComment',
    commenterUser: commenterUser,
    commenterEmail: commenterEmail,
    theComment: theComment,
    pnum: pnum}, (data, status, xhr) => {
      if(status == 'success'){
        if(data == 'commented'){
          this.setState({
            comments: data
          })
        }else{

        }
      }
    });

好的,谢谢。这篇文章非常全面,感谢您的时间 :) - sinawic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接