首先引用个例子react
class Example extends React.Component {
constructor() {
super();
this.state = {
val: 0
};
}
componentDidMount() {
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1});
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);
}
render() {
return null;
}
};
复制代码
以上代码依次输出结果是?不知道的结果的能够接下来看 知道结果的能够直接跳过 结果依次是0 0 2 3 下面剖析下setState应用场景git
......
state = { val: 0 }
componentDidMount() {
this.setState({
val: this.state.val + 1
})
console.log(this.state.val)
}
......
复制代码
这里的输出值仍是初始值0 看下源码 关于github
function enqueueUpdate(component) {
......
if (!batchingStrategy.isBatchingUpdates) {
batchingStrategy.batchedUpdates(enqueueUpdate, component);
return;
}
dirtyComponents.push(component);
......
}
复制代码
看到有个if判断 isBatchchingUpdates true & false 自行打个断点能够看到这componentDidMount时候已经将isBatchingUpdates设置了为true 全部就会执行dirtyComponents.push(component); 不会立马更新state 这时候打印就仍是初始值 0promise
这个if判断的过程看似成了一个异步的操做bash
......
state = { val: 0 }
componentDidMount() {
setTimeout( () => {
this.setState({
val: this.state.val + 1
})
console.log(this.state.val)
})
}
......
复制代码
这里打印的是1 断点看到这时候没有batchedUpdate调用 isBatchingUpdates仍是为false 这样batchingStrategy.batchedUpdates(enqueueUpdate, component); 这就话就当即生效了 全部这时候val 会当即更新 打印是1异步
......
state = { val: 0 }
componentDidMount() {
this.setState({ val: this.state.val + 1 })
this.setState({ val: this.state.val + 1 })
this.setState({ val: this.state.val + 1 })
}
......
复制代码
这里结果仍是最后一个1 有一个update队列 对最后一个更新async
var stateQueue = [] // state队列
function mysetState(state, componentstate) {
// 写一个异步的操做
if ( stateQueue.length === 0 ) {
promiseasync( cleanflush ); // 清空队列
}
stateQueue.push({
state,
componentstate
})
}
function cleanflush() {
var item =setStateQueue.shift()
while(item) {
const { state, componentstate } = item
// 设置一个preState 保存以前的
if(!componentstate.prevState) {
componentstate.prevState = Object.assign( {}, componentstate.state);
}
if(typeof state === 'function') { // 判断是否为回调
Object.assign( componentstate.state, state( componentstate.prevState, componentstate.props ));
} else {
Object.assign(componentstate.state, state) // 合并state
}
}
}
function promiseasync(fn) {
return Promise.resolve().then(function() {
fn
})
}
复制代码