Javascript ES6/React“;这";使用ajax从服务器获取数据的关键字(教程)

Javascript ES6/React“;这";使用ajax从服务器获取数据的关键字(教程),javascript,class,reactjs,this,ecmascript-6,Javascript,Class,Reactjs,This,Ecmascript 6,我正在遵循这一原则,并试图将其翻译成ES6。但是,当我将CommentBox更改为ES6类时,它开始给我一个this.props.url是未定义的错误(在loadCommentsFromServer中的AJAX调用中)。我认为这与ES6如何绑定this有关,但我对这门语言不太熟悉(也不太熟悉),所以我不确定。我已经看过了,并且看到了: React.createClass有一个内置的神奇功能,可以为您自动将所有方法绑定到this。对于其他类中不习惯此功能的JavaScript开发人员来说,这可能有

我正在遵循这一原则,并试图将其翻译成ES6。但是,当我将
CommentBox
更改为ES6类时,它开始给我一个
this.props.url
未定义的
错误(在
loadCommentsFromServer
中的AJAX调用中)。我认为这与ES6如何绑定
this
有关,但我对这门语言不太熟悉(也不太熟悉),所以我不确定。我已经看过了,并且看到了:

React.createClass有一个内置的神奇功能,可以为您自动将所有方法绑定到
this
。对于其他类中不习惯此功能的JavaScript开发人员来说,这可能有点让人困惑,或者当他们从React移动到其他类时,这可能会让人困惑

我不太确定,但我认为这意味着我必须保存这个值(如
let that=this
.bind(that)
),但这也给出了相同的
this.props.url
未定义的
-我不确定下一步该去哪里

以下是我当前的代码:

class CommentBox extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: []
    };
  }
  loadCommentsFromServer() {
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      cache: false,
      success: function(data) {
        this.setState({
          data: data
        })
      }.bind(this)
    });
  }
  handleCommentSubmit(comment) {
    var comments = this.state.data;
    var newComments = comments.concat([comment]);
    this.setState({ data: newComments });
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      type: 'POST',
      data: comment,
      success: function(data) {
        this.setState({ data: data });
      },
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  }
  componentDidMount() {
    this.loadCommentsFromServer();
    setInterval(this.loadCommentsFromServer, this.props.pollInterval);
  }
  render() {
    return (
      <div className="commentBox">
        <h1>Comments</h1>
        <CommentList data={this.state.data}/>
        <CommentForm onCommentSubmit={this.handleCommentSubmit}/>
      </div>
    );
  }
};
class CommentBox扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
数据:[]
};
}
loadCommentsFromServer(){
$.ajax({
url:this.props.url,
数据类型:“json”,
cache:false,
成功:功能(数据){
这是我的国家({
数据:数据
})
}.绑定(此)
});
}
handleCommentSubmit(评论){
var注释=this.state.data;
var newComments=comments.concat([comment]);
this.setState({data:newcommons});
$.ajax({
url:this.props.url,
数据类型:“json”,
键入:“POST”,
数据:评论,
成功:功能(数据){
this.setState({data:data});
},
错误:函数(xhr、状态、错误){
console.error(this.props.url,status,err.toString());
}.绑定(此)
});
}
componentDidMount(){
this.loadCommentsFromServer();
setInterval(this.loadCommentsFromServer,this.props.pollInterval);
}
render(){
返回(
评论
);
}
};

在诸如success和error之类的回调函数中,作用域会发生变化,因此“this”不再是CommentBox

您需要执行以下操作:

handleCommentSubmit(comment) {
    var comments = this.state.data;
    var newComments = comments.concat([comment]);
    this.setState({ data: newComments });
    var comment_box = this;
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      type: 'POST',
      data: comment,
      success: function(data) {
        comment_box.setState({ data: data });
      },
      error: function(xhr, status, err) {
        console.error(comment_box.props.url, status, err.toString());
      }.bind(this)
    });
  }
将其应用于代码中的其他适用位置

您需要使用绑定(this)来绑定事件。如下图所示:

componentDidMount() {
    this.loadCommentsFromServer().bind(this);
    setInterval(this.loadCommentsFromServer.bind(this), this.props.pollInterval);
  }
您可以从以下链接阅读参考:

没有自动绑定
方法遵循与常规ES6类相同的语义,这意味着它们不会自动将其绑定到实例。您必须显式使用.bind(this)或arrow函数=>。

这是特定于作为ES6类实现的
React.Component
的行为。使用ES5样式时,React组件自动绑定其所有功能。使用ES6类样式时,自动绑定的唯一方法是
React.Component
render
componentDidMount
等)中专门包含的方法

事实上,这很容易被忽视


别难过;我知道它在文档中,因为我第一次将一些可用的React组件移植到ES6类中时,我不得不去寻找它。

当它使用ES5和
React.createClass编写时,它是可用的。ES6中有没有改变
这个
绑定到回调函数的方式?我不确定。我还建议在回调函数中添加console.log(this),以便您可以验证“this”是什么。好的,所以
this
只工作一次(它显示了正确的对象),然后它开始给我未定义的错误抱歉,您能更具体地说明哪个部分工作一次吗?哪一部分又给了你未定义的错误?它仍然是loadCommentsFromServer()吗?在所有回调中放置console.log(此)后,请告诉我。你把我上面的方法应用到loadCommentsFromServer()了吗?既然我不能在这个例子中使用箭头函数,我想
bind(this)
是唯一的解决方案。我犯了一个错误,在那之前“this.loadCommentsFromServer()”不能绑定(this)。顺便说一句,如果你想使用箭头函数。唯一的方法是这样的:setInterval(()=>{$.ajax)({url:this.props.url,数据类型:'json',缓存:false,成功:函数(数据){this.setState({data:data})}.bind(this)};},this.props.pollInterval);