【问题标题】:ES6/React "this" keyword with ajax to get data from server (tutorial) [duplicate]ES6 / React“this”关键字与ajax从服务器获取数据(教程)[重复]
【发布时间】:2015-12-20 04:46:10
【问题描述】:

我正在关注React Beginner Tutorial,我正在尝试将其翻译成 ES6。但是,当我将 CommentBox 更改为 ES6 类时,它开始给我一个 this.props.urlundefined 错误(在 loadCommentsFromServer 的 AJAX 调用中)。我认为这与 ES6 绑定 this 的方式有关,但是我对这种语言(也不是 React)不太熟悉,所以我不确定。我查看了React 0.13 release notes 并看到了这个:

React.createClass 有一个内置的魔法特性,可以自动为你将所有方法绑定到this。对于不习惯在其他类中使用此功能的 JavaScript 开发人员来说,这可能会有些混乱,或者当他们从 React 转移到其他类时可能会感到困惑。

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

这是我当前的代码:

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>
    );
  }
};

【问题讨论】:

    标签: javascript class reactjs this ecmascript-6


    【解决方案1】:

    在成功和错误等回调函数中,范围发生变化,因此“this”不再是评论框。

    您需要执行以下操作:

    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)
        });
      }
    

    将此应用到代码中其他适用的地方

    【讨论】:

    • 它在使用 ES5 和 React.createClass 编写时可以工作,ES6 中是否有任何改变 this 绑定回调函数的方式?
    • 我不确定。我还建议在回调函数中添加 console.log(this),这样您就可以验证“this”是什么。
    • 好的,this 工作一次(它显示正确的对象)然后它开始给我未定义的错误
    • 抱歉,您能更具体地说明哪一部分有效吗?哪个部分再次给您未定义的错误?仍然是 loadCommentsFromServer() 吗?将 console.log(this) 放入所有回调后告诉我。您是否将我上面的方法应用于 loadCommentsFromServer() ?
    【解决方案2】:

    你需要使用 bind(this) 来绑定你的事件。如下:

    componentDidMount() {
        this.loadCommentsFromServer().bind(this);
        setInterval(this.loadCommentsFromServer.bind(this), this.props.pollInterval);
      }
    

    您可以从此链接阅读参考: https://facebook.github.io/react/docs/reusable-components.html#no-autobinding

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

    【讨论】:

    • 因为在这种情况下我不能使用箭头函数,我猜bind(this) 是唯一的解决方案?
    • 我之前犯了一个错误,“this.loadCommentsFromServer()”不能绑定(this)。
    • 顺便说一句,如果你想使用箭头函数。唯一的方法是这样的:setInterval(()=>{ $.ajax({ url: this.props.url, dataType: 'json' , 缓存: false, 成功: function(data) { this.setState({ data: data }) }.bind(this) });},this.props.pollInterval);
    【解决方案3】:

    这是 React.Component 作为 ES6 类的实现所特有的行为。当使用 ES5 风格时,React 组件会自动绑定它们的所有功能。当您使用 ES6 类样式时,自动绑定的唯一方法是那些专门包含在 React.Component 中的方法(rendercomponentDidMount 等)。

    这实际上是mentioned in the documentation,虽然很容易被忽略。

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

    【讨论】:

      猜你喜欢
      • 2019-11-18
      • 2023-03-17
      • 2017-04-26
      • 1970-01-01
      • 2016-05-16
      • 1970-01-01
      • 1970-01-01
      • 2019-07-21
      • 1970-01-01
      相关资源
      最近更新 更多