我们大家都知道 react 的 setState 是异步的(也可以理解成同步的),在react 组件声明周期内的多次 setState 会进行合并处理。
看下面代码
componentDidMount(){ this.setState({ count:0 }) this.setState({ count: 1 }) this.setState({ count: 2 }) this.setState({ count: 3 }); console.log(this.state); }
setState 内部将数据进行合并,主要使用了共享结构,下面是模拟的伪代码实现。
function React(){ this.state={}; this.nextState=null;//保存合并后的state this.renderEndCallback=[];//保存回调方法 } React.prototype.setState=function(obj,callback){ //obj是对象 if(obj && typeof obj === 'object'){//如果是对象则进行合并 this.nextState = {...this.state,...this.nextState,...obj}; if(typeof callback==='function'){ this.renderEndCallback.push(callback); } } //obj 是函数 if(obj && typeof obj==='function'){ this.nextState = this.nextState ? this.nextState:({...this.state}); var tempState = obj(this.nextState);//此处省略 props 参数 //进行state 的合并 this.nextState = {...this.state,...this.nextState,...tempState}; } } //获得最新 stateReact.prototype.getState=function(){ this.state={...this.nextState}; return this.state;} // 用来获得最新的stateReact.prototype.render=function(){ var state=this.getState(); this.renderEndCallback.forEach((fn)=>(fn.call(this)));}
调用
var title = new React(); title.state={ count:0, name:'前端张大胖'} title.setState({ count:1}); console.log(1,title.state); title.setState({ count:2},function(){ console.log(2,'callback',this.state);}); console.log(3,title.state); title.setState((preState)=>{ return { count:preState.count+3, age:25, address:'北京' }}); console.log(4,title.state); title.setState({ count:1}); title.setState((preState)=>{ console.log(5,preState); return { count:preState.count+3 }}); title.render();
执行结果
以上模拟代码并非是 react 内部实现逻辑,只是模拟实现了相同的的输出结果,如有问题还请指正。