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

时间:2016-03-31 15:26:06

标签: reactjs ecmascript-6

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

  

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

这是我的CommentBox文件/代码:

public static Path DrawBezeireUsingTwoPoints(Point startPoint, Point endPoint)
{
  Path path = new Path();
  PathFigure pathFigure = new PathFigure();
  // Set up the Path to insert the segments
  PathGeometry pathGeometry = new PathGeometry();
  BezierSegment bezeireSeg;
  // Draw an ellipse passing by the 2 points and let the path cross it
  Point beziereMidPoint = CalculateBezierePoint(startPoint, endPoint, true);
  bezeireSeg = new BezierSegment(startPoint, beziereMidPoint, endPoint, true);

  pathFigure.StartPoint = startPoint;
  pathFigure.IsClosed = false;
  pathFigure.Segments.Add(bezeireSeg);

  pathGeometry.Figures.Add(pathFigure);
  path.Data = pathGeometry;
  path.Stroke = Brushes.Brown;
  path.StrokeThickness = 2;
  return path;
}

错误发生在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> ); } } ;似乎不知道loadCommentsFromServer是什么。我认为这是此引用问题并找到了similar question,建议使用新的ES6箭头来解决问题。然后我尝试了this.props,但是Browserify抱怨并且没有构建。

2 个答案:

答案 0 :(得分:6)

这一行是你的问题:

setInterval(this.loadCommentsFromServer, this.props.pollInterval);

您正在将方法loadCommentsFromServer传递给setInterval,但会在没有上下文的情况下调用它,因此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); 

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

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

componentWillUnmount() {
   clearInterval(this.intervalId);
}

答案 1 :(得分:1)

  

我认为这是一个参考问题,谷歌搜索我发现   一个类似的stackoverflow问题,他们建议使用新的ES6   箭头来解决问题。我尝试使用:loadCommentsFromServer = () => {}但是浏览器抱怨并且不构建:/

ES6箭头功能确实可以解决您的问题。构建错误是因为ES6不支持类属性,loadCommentsFromServer =是类属性初始值设定项。启用ES7 class properties并且您应该能够执行此操作,它可以解决您的问题,而无需手动bind或在您调用setInterval时将回调包装在新的胖箭头函数中。