ES6/React "this" 关键字和 ajax 从服务器获取数据(教程)
ES6/React "this" keyword with ajax to get data from server (tutorial)
我正在关注 React Beginner Tutorial and I'm trying to translate it into ES6. However when I changed the CommentBox
to an ES6 class it started giving me a this.props.url
is undefined
error (in the AJAX call in loadCommentsFromServer
). I think this has something to do with how ES6 binds this
, but this I'm not very familiar with the language (nor React) so I'm not sure. I've looked at the React 0.13 release notes 并且看到了这个:
React.createClass has a built-in magic feature that bound all methods to this
automatically for you. This can be a little confusing for JavaScript developers that are not used to this feature in other classes, or it can be confusing when they move from React to other classes.
我不太确定,但我认为这意味着我必须保存它的值(如 let that = this
和 .bind(that)
)但它也给出了相同的 this.props.url
是 undefined
- 我不确定下一步要去哪里。
这是我当前的代码:
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>
);
}
};
在成功和错误等回调函数中,范围发生变化,因此 "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)
});
}
将此应用到代码中的其他适用位置
您需要使用 bind(this) 来绑定您的事件。如下所示:
componentDidMount() {
this.loadCommentsFromServer().bind(this);
setInterval(this.loadCommentsFromServer.bind(this), this.props.pollInterval);
}
您可以从这个 link 中阅读参考资料:
https://facebook.github.io/react/docs/reusable-components.html#no-autobinding
没有自动绑定
方法遵循与常规 ES6 类 相同的语义,这意味着它们不会自动将 this 绑定到实例。您必须明确使用 .bind(this) 或箭头函数 =>.
这是 React.Component
作为 ES6 class 实现的特定行为。当使用 ES5 风格时,React 组件会自动绑定它们的所有功能。当您使用 ES6 class 样式时,自动绑定的唯一方法是那些明确包含在 React.Component
中的方法(render
、componentDidMount
等)。
这实际上是 mentioned in the documentation,虽然它很容易被忽略。
不要难过;我知道它在文档中,因为我第一次将一些可用的 React 组件移植到 ES6 classes.
时不得不去寻找它
我正在关注 React Beginner Tutorial and I'm trying to translate it into ES6. However when I changed the CommentBox
to an ES6 class it started giving me a this.props.url
is undefined
error (in the AJAX call in loadCommentsFromServer
). I think this has something to do with how ES6 binds this
, but this I'm not very familiar with the language (nor React) so I'm not sure. I've looked at the React 0.13 release notes 并且看到了这个:
React.createClass has a built-in magic feature that bound all methods to
this
automatically for you. This can be a little confusing for JavaScript developers that are not used to this feature in other classes, or it can be confusing when they move from React to other classes.
我不太确定,但我认为这意味着我必须保存它的值(如 let that = this
和 .bind(that)
)但它也给出了相同的 this.props.url
是 undefined
- 我不确定下一步要去哪里。
这是我当前的代码:
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>
);
}
};
在成功和错误等回调函数中,范围发生变化,因此 "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)
});
}
将此应用到代码中的其他适用位置
您需要使用 bind(this) 来绑定您的事件。如下所示:
componentDidMount() {
this.loadCommentsFromServer().bind(this);
setInterval(this.loadCommentsFromServer.bind(this), this.props.pollInterval);
}
您可以从这个 link 中阅读参考资料: https://facebook.github.io/react/docs/reusable-components.html#no-autobinding
没有自动绑定 方法遵循与常规 ES6 类 相同的语义,这意味着它们不会自动将 this 绑定到实例。您必须明确使用 .bind(this) 或箭头函数 =>.
这是 React.Component
作为 ES6 class 实现的特定行为。当使用 ES5 风格时,React 组件会自动绑定它们的所有功能。当您使用 ES6 class 样式时,自动绑定的唯一方法是那些明确包含在 React.Component
中的方法(render
、componentDidMount
等)。
这实际上是 mentioned in the documentation,虽然它很容易被忽略。
不要难过;我知道它在文档中,因为我第一次将一些可用的 React 组件移植到 ES6 classes.
时不得不去寻找它