Component.prototype.setState = function (partialState, callback) { // 可以看到参数仅仅接收 object/null/function 否则会报错 (function () { if (!(typeof partialState === 'object' || typeof partialState === 'function' || partialState == null)) { { throw ReactError(Error('setState(...): takes an object of state variables to update or a function which returns an object of state variables.')); } } })(); this.updater.enqueueSetState(this, partialState, callback, 'setState'); };
exportfunctionenqueueUpdate<State>(fiber: Fiber, update: Update<State>) { // Update queues are created lazily. // 使用alternate属性双向连接一个当前fiber和其work-in-progress,当前fiber实例的alternate属性指向其work-in-progress,work-in-progress的alternate属性指向当前稳定fiber。 const alternate = fiber.alternate; let queue1; let queue2; if (alternate === null) { // There's only one fiber. queue1 = fiber.updateQueue; queue2 = null; if (queue1 === null) { //如果当前组件没有等待setState的队列则创建一个, // 利用fiber当前已经记录并需要整合的state存储到queue1与fiber.updateQueue queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); } } else { // There are two owners. // 如果fiber树以及workinprogress树都存在,下面的逻辑则会同步两个树的update队列 queue1 = fiber.updateQueue; queue2 = alternate.updateQueue; // 当两个树的队列至少有一个不存在的时候执行队列创建或者复制操作 if (queue1 === null) { if (queue2 === null) { // Neither fiber has an update queue. Create new ones. // 两个队列都没有则根据各自的memoizedState创建update队列 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); queue2 = alternate.updateQueue = createUpdateQueue( alternate.memoizedState, ); } else { // 如果有一个没有则复制另一个队列给它 // Only one fiber has an update queue. Clone to create a new one. queue1 = fiber.updateQueue = cloneUpdateQueue(queue2); } } else { if (queue2 === null) { // 如果有一个没有则复制另一个队列给它 // Only one fiber has an update queue. Clone to create a new one. queue2 = alternate.updateQueue = cloneUpdateQueue(queue1); } else { // Both owners have an update queue. } } }
if (queue2 === null || queue1 === queue2) { // There's only a single queue. // 如果只有一个树,或者两棵树队列是同一个,则将传入的更新对象添加到第一个队列中 appendUpdateToQueue(queue1, update); } else { // There are two queues. We need to append the update to both queues, // while accounting for the persistent structure of the list — we don't // want the same update to be added multiple times. // 如果两个队列存在,则将更新任务加入两个队列中,并避免被添加多次 if (queue1.lastUpdate === null || queue2.lastUpdate === null) { // One of the queues is not empty. We must add the update to both queues. // 有一个队列不为空,将update添加到两个队列 appendUpdateToQueue(queue1, update); appendUpdateToQueue(queue2, update); } else { // Both queues are non-empty. The last update is the same in both lists, // because of structural sharing. So, only append to one of the lists. appendUpdateToQueue(queue1, update); // But we still need to update the `lastUpdate` pointer of queue2. queue2.lastUpdate = update; } } }