ajax - 在 setState() 回调中发出 AJAX 请求

标签 ajax concurrency reactjs

我一直在编写我的 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 可能会乱序执行。因此,可能发生的最糟糕的情况是“正在加载”状态永远不会被渲染。这就是后一种风格想要解决的问题吗?还有其他我没有看到的风险吗?

最佳答案

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));
<小时/>

为了获得最佳结果,请将所有这些抽象为高阶组件或混合。您不想在每个获取数据的组件中处理此逻辑。

关于ajax - 在 setState() 回调中发出 AJAX 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29973238/

相关文章:

windows - 一个进程的 read() 可以看到另一个进程的部分 write() 吗?

java - Java 5 中的 Lock 和 ReentrantLock 有什么区别?

html - React HTML 选择选项在 Chrome 中不起作用

javascript - JSON响应数据中的数据长度

php - 使用ajax发送输入类型文件值

javascript - 如何解析远程服务器返回的JSONP数据

javascript - 跨多个 SPA 应用共享 CSS (React)

jquery - ListView 过滤器不过滤新项目

multithreading - 并发和多线程

reactjs - 如何在 React 16.x 中比较以前的上下文和当前的上下文?