为什么在我的ReactJS代码中未定义this.props?

Gio*_*tta 1 ecmascript-6 reactjs

在我学习React和ES6的路上,我参加了官方教程,并开始使其与ES6兼容.但是当涉及到执行Ajax请求时,我收到以下错误:

CommentBox.js:23未捕获TypeError:无法读取未定义的属性'url'

这是我的CommentBox文件/代码:

import React from 'react';
import CommentList from './CommentList.js';
import CommentForm from './CommentForm.js';

export default class CommentBox extends React.Component {
  constructor(props) {
    super(props);
    console.log(this.props)
    this.state = {
      data: []
    }
  }

  loadCommentsFromServer() {
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      cache: false,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  }

  handleCommentSubmit(comment) {
    let comments = this.state.data;

    // Optimistically set  id on the new comment.
    // It will be replaced by an id generated by the server.
    // In a production you would have a more robust system in place.
    comment.id = Date.now();
    let 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});
      }.bind(this),
      error: function(xhr, status, err) {
        this.setState({data: comments});
        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>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

错误发生在loadCommentsFromServer; 似乎不知道是什么this.props.我认为这是一个参考问题,并发现了一个 类似的问题,建议使用新的ES6箭头来解决问题.然后我尝试了:loadCommentsFromServer = () => {},但Browserify抱怨并且没有构建.

Wic*_*ams 6

这行是你的问题:

setInterval(this.loadCommentsFromServer, this.props.pollInterval);
Run Code Online (Sandbox Code Playgroud)

您正在将方法传递loadCommentsFromServersetInterval,但它将在没有上下文的情况下调用,因此this将不再绑定到您的组件(this将绑定到窗口).相反,你应该做这样的事情:

setInterval(this.loadCommentsFromServer.bind(this), this.props.pollInterval);
// OR... use a fat arrow, which preserves `this` context
setInterval(() => this.loadCommentsFromServer(), this.props.pollInterval); 
Run Code Online (Sandbox Code Playgroud)

最后,您应该存储间隔ID,以便在卸载组件时清除它:

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

componentWillUnmount() {
   clearInterval(this.intervalId);
}
Run Code Online (Sandbox Code Playgroud)