当我们有了前面知识的铺垫,就很容易理解this.setState的工作流程。
流程概览
可以看到,this.setState内会调用this.updater.enqueueSetState方法。
Component.prototype.setState = function (partialState, callback) {if (!(typeof partialState === 'object' || typeof partialState === 'function' || partialState == null)) {{throw 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');};
你可以在这里
(opens new window)看到这段代码
在enqueueSetState方法中就是我们熟悉的从创建update到调度update的流程了。
enqueueSetState(inst, payload, callback) {// 通过组件实例获取对应fiberconst fiber = getInstance(inst);const eventTime = requestEventTime();const suspenseConfig = requestCurrentSuspenseConfig();// 获取优先级const lane = requestUpdateLane(fiber, suspenseConfig);// 创建updateconst update = createUpdate(eventTime, lane, suspenseConfig);update.payload = payload;// 赋值回调函数if (callback !== undefined && callback !== null) {update.callback = callback;}// 将update插入updateQueueenqueueUpdate(fiber, update);// 调度updatescheduleUpdateOnFiber(fiber, lane, eventTime);}
你可以在这里
(opens new window)看到
enqueueSetState代码
这里值得注意的是对于ClassComponent,update.payload为this.setState的第一个传参(即要改变的state)。
this.forceUpdate
在this.updater上,除了enqueueSetState外,还存在enqueueForceUpdate,当我们调用this.forceUpdate时会调用他。
可以看到,除了赋值update.tag = ForceUpdate;以及没有payload外,其他逻辑与this.setState一致。
enqueueForceUpdate(inst, callback) {const fiber = getInstance(inst);const eventTime = requestEventTime();const suspenseConfig = requestCurrentSuspenseConfig();const lane = requestUpdateLane(fiber, suspenseConfig);const update = createUpdate(eventTime, lane, suspenseConfig);// 赋值tag为ForceUpdateupdate.tag = ForceUpdate;if (callback !== undefined && callback !== null) {update.callback = callback;}enqueueUpdate(fiber, update);scheduleUpdateOnFiber(fiber, lane, eventTime);},};
你可以在这里
(opens new window)看到
enqueueForceUpdate代码
那么赋值update.tag = ForceUpdate;有何作用呢?
在判断ClassComponent是否需要更新时有两个条件需要满足:
const shouldUpdate =checkHasForceUpdateAfterProcessing() ||checkShouldComponentUpdate(workInProgress,ctor,oldProps,newProps,oldState,newState,nextContext,);
你可以在这里
(opens new window)看到这段代码
checkHasForceUpdateAfterProcessing:内部会判断本次更新的
Update是否为ForceUpdate。即如果本次更新的Update中存在tag为ForceUpdate,则返回true。checkShouldComponentUpdate:内部会调用
shouldComponentUpdate方法。以及当该ClassComponent为PureComponent时会浅比较state与props。
你可以在这里
(opens new window)看到
checkShouldComponentUpdate代码
所以,当某次更新含有tag为ForceUpdate的Update,那么当前ClassComponent不会受其他性能优化手段(shouldComponentUpdate|PureComponent)影响,一定会更新。
总结
至此,我们学习完了HostRoot | ClassComponent所使用的Update的更新流程。
在下一章我们会学习另一种数据结构的Update —— 用于Hooks的Update。

(opens new window)