在React中,setState方法是用于更新组件状态的重要方法。当setState被调用时,React会对组件进行重新渲染,以反映状态的变化。
具体的执行过程如下:
调用setState入口函数:当你在组件中调用setState方法时,实际上是调用了React组件的setState方法。这个方法在内部充当一个分发器的角色,根据传入的参数,将其分发到不同的功能函数中去。
ReactComponent.prototype.setState = function (partialState, callback) {
this.updater.enqueueSetState(this, partialState);
if (callback) {
this.updater.enqueueCallback(this, callback, 'setState');
}
};
- :
enqueueSetState
方法将新的state放进组件的状态队列里,并调用enqueueUpdate
来处理将要更新的实例对象。enqueueSetState: function (publicInstance, partialState) { // 根据 this 拿到对应的组件实例 var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'setState'); // 这个 queue 对应的就是一个组件实例的 state 数组 var queue = internalInstance._pendingStateQueue || (internalInstance._pendingStateQueue = []); queue.push(partialState); // enqueueUpdate 用来处理当前的组件实例 enqueueUpdate(internalInstance); }
在enqueueUpdate
方法中,React会检查当前是否正在进行批量更新。如果是,那么组件会被添加到dirtyComponents
队列中,等待下一次的批量更新。如果不是,那么React会立即开始批量更新
function enqueueUpdate(component) {
ensureInjected();
// 注意这一句是问题的关键,isBatchingUpdates标识着当前是否处于批量创建/更新组件的阶段
if (!batchingStrategy.isBatchingUpdates) {
// 若当前没有处于批量创建/更新组件的阶段,则立即更新组件
batchingStrategy.batchedUpdates(enqueueUpdate, component);
return;
}
// 否则,先把组件塞入 dirtyComponents 队列里,让它“再等等”
dirtyComponents.push(component);
if (component._updateBatchNumber == null) {
component._updateBatchNumber = updateBatchNumber + 1;
}
}