加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

关于React的setState异步更新问题

发布时间:2020-12-15 20:26:50 所属栏目:百科 来源:网络整理
导读:1. 同一个生命周期里,多个setState()会只执行最后一个,而放入setTimeout()中的异步函数中的setState()有几个便执行几个; componentDidMount() { this .setState({ val: this .state.val+1 },() = console.log( this .state.val)); // setState()是异步更

1. 同一个生命周期里,多个setState()会只执行最后一个,而放入setTimeout()中的异步函数中的setState()有几个便执行几个;

componentDidMount() {
        this.setState({
            val: this.state.val+1
        },() => console.log(this.state.val));  // setState()是异步更新,所以第二个是更新后的回调函数,如果回调成功,可以打印出回调后的state
        console.log(this.state.val);
        this.setState({
            val: this.state.val+1
        },() => console.log(this.state.val));
        console.log(this.state.val);
        setTimeout(() => {
            this.setState({
                val: this.state.val+1
            });
            console.log(this.state.val);
            this.setState({
                val: this.state.val+1
            });
            console.log(this.state.val);
        },0)
    }
执行结果:0,0,1,1,2,3

源码解释:

setState通过enqueueUpdate()方法执行state更新,那么需要知道enqueueUpdate()方法的内部实现:

function enqueueUpdate(component) {
            ensureInjected();
            // 如果不处于批量更新模式,那么将遍历dirtyComponents,调用updateComponent,更新states/props
            if (!batchingStrategy.isBatchingUpdates) {
                batchingStrategy.batchedUpdates(enqueueUpdate,component);
                return;
            }
            // 如果处于批量更新模式,则将该组件保存在dirtyComponents中
            dirtyComponents.push(component);
        }
        
        var ReactDefaultBatchingStrategy = {
            isBatchingUpdates: false,batchedUpdates: function (callback,a,b,c,d,e) {
                var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates;
                ReactDefaultBatchingStrategy.isBatchingUpdates = true;
                if (alreadyBatchingUpdates) {
                    callback(a,e)
                } else {
                    transaction.perform(callback,null,e)
                }
            }
        }

在生命周期钩子(react定义的事件机制) componentDidMount()中setState()时,isBatchingUpdates这个属性已经设置为true,所以会进入批量更新模式,所以两次打印都是0;

在setTimeout()中,没有前置的batchedUpdate调用,所以isBatchingUpdates这个属性为false,则会进入第一种模式,setState()执行一次,则立即更新一次;

react内部的生命周期钩子的函数走的是react内部的事件机制(事务);在dom绑定的事件,定时器等一些非react事件中的setState()走的是正常的事件机制;

这里说明下:

在按钮原生事件中定义的setState,和定时器效果一样,每次setState都会引起新的render
react事件是合并的成一次render的。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读