关于React的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) } 源码解释: 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()走的是正常的事件机制; 这里说明下: 在按钮原生事件中定义的 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |