在我学习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抱怨并且没有构建。
答案 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
时将回调包装在新的胖箭头函数中。