在 setState() 的回调中发出 AJAX 请求
Issuing AJAX request in the callback of setState()
我一直在像这样编写我的 ReactJS AJAX 请求:
this.setState({
isLoading: true,
results: null
});
$.get(ajaxUrl, function(results) {
this.setState({
isLoading: false,
results: results
});
}.bind(this));
这只是一个示例,它缺少错误处理、限制、取消请求等。但要点就在那里。我基本上要求设置一些状态,然后然后发出请求。
查看 GitHub 上的一些其他代码,不过,我注意到有些人在 setState 回调中编写了他们的 AJAX 调用:
this.setState({
isLoading: true,
results: null
}, function() {
$.get(ajaxUrl, function(results) {
this.setState({
isLoading: false,
results: results
});
}.bind(this));
}.bind(this));
这样做有正当理由吗? The docs say:
There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.
所以不能保证 setState 在返回之前改变状态,但我没有看到不同的 setState 可能会乱序执行。所以可能发生的最坏情况是 "loading" 状态永远不会被渲染。这是后一种风格试图解决的问题吗?还有其他我没有看到的风险吗?
but I see no mention that different setState's may execute out of order
更正它们的顺序 运行,从用户体验的角度来看,您不希望显示加载指示器的时间少于半秒。
需要这个的情况看起来更像这样:
this.setState({
isLoading: true,
results: this.state.results || []
}, function() {
$.get(ajaxUrl, function(results) {
this.setState({
isLoading: false,
// note! we're referring to state here
results: this.state.results.concat(results)
});
}.bind(this));
}.bind(this));
不过,这也可以通过将回调传递给 setState 而不是对象来解决。这样,我们就可以在任何先前排队的更新发生后查看状态。
It's also possible to pass a function with the signature function(state, props). This can be useful in some cases when you want to enqueue an atomic update that consults the previous value of state+props before setting any values.
– Component Api Docs
this.setState({
isLoading: true,
results: null
});
$.get(ajaxUrl, function(results) {
this.setState(function(state){
return {
isLoading: false,
results: state.results.concat(results)
};
});
}.bind(this));
为了获得最佳结果,请将所有这些抽象为高阶组件或混入。您不想在每个获取数据的组件中处理此逻辑。
我一直在像这样编写我的 ReactJS AJAX 请求:
this.setState({
isLoading: true,
results: null
});
$.get(ajaxUrl, function(results) {
this.setState({
isLoading: false,
results: results
});
}.bind(this));
这只是一个示例,它缺少错误处理、限制、取消请求等。但要点就在那里。我基本上要求设置一些状态,然后然后发出请求。
查看 GitHub 上的一些其他代码,不过,我注意到有些人在 setState 回调中编写了他们的 AJAX 调用:
this.setState({
isLoading: true,
results: null
}, function() {
$.get(ajaxUrl, function(results) {
this.setState({
isLoading: false,
results: results
});
}.bind(this));
}.bind(this));
这样做有正当理由吗? The docs say:
There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.
所以不能保证 setState 在返回之前改变状态,但我没有看到不同的 setState 可能会乱序执行。所以可能发生的最坏情况是 "loading" 状态永远不会被渲染。这是后一种风格试图解决的问题吗?还有其他我没有看到的风险吗?
but I see no mention that different setState's may execute out of order
更正它们的顺序 运行,从用户体验的角度来看,您不希望显示加载指示器的时间少于半秒。
需要这个的情况看起来更像这样:
this.setState({
isLoading: true,
results: this.state.results || []
}, function() {
$.get(ajaxUrl, function(results) {
this.setState({
isLoading: false,
// note! we're referring to state here
results: this.state.results.concat(results)
});
}.bind(this));
}.bind(this));
不过,这也可以通过将回调传递给 setState 而不是对象来解决。这样,我们就可以在任何先前排队的更新发生后查看状态。
It's also possible to pass a function with the signature function(state, props). This can be useful in some cases when you want to enqueue an atomic update that consults the previous value of state+props before setting any values.
– Component Api Docs
this.setState({
isLoading: true,
results: null
});
$.get(ajaxUrl, function(results) {
this.setState(function(state){
return {
isLoading: false,
results: state.results.concat(results)
};
});
}.bind(this));
为了获得最佳结果,请将所有这些抽象为高阶组件或混入。您不想在每个获取数据的组件中处理此逻辑。