在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'); } };
1: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; } }