You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
case ClassComponent: {constComponent=workInProgress.type;constunresolvedProps=workInProgress.pendingProps;constresolvedProps=workInProgress.elementType===Component
? unresolvedProps
: resolveDefaultProps(Component,unresolvedProps);returnupdateClassComponent(current,workInProgress,Component,resolvedProps,renderExpirationTime,);}
updateClassComponent
functionupdateClassComponent(current: Fiber|null,workInProgress: Fiber,Component: any,nextProps,renderExpirationTime: ExpirationTime,){// ...context 相关// classComponent 通过 new class 获取的实例对象constinstance=workInProgress.stateNode;// 通过这个变量判断是否更新componentletshouldUpdate;// 首次 render 时不存在,或者class组件第一次渲染if(instance===null){// 如果非首次渲染,而 instance 不存在,表示的是 suspended 异步组件的情况if(current!==null){// An class component without an instance only mounts if it suspended// inside a non- concurrent tree, in an inconsistent state. We want to// tree it like a new mount, even though an empty version of it already// committed. Disconnect the alternate pointers.current.alternate=null;workInProgress.alternate=null;// Since this is conceptually a new fiber, schedule a Placement effectworkInProgress.effectTag|=Placement;}// In the initial pass we might need to construct the instance.// 创建 instanceconstructClassInstance(workInProgress,Component,nextProps,renderExpirationTime,);// 挂载 class组件mountClassInstance(workInProgress,Component,nextProps,renderExpirationTime,);shouldUpdate=true;}elseif(current===null){// instance !== null,之前首次挂载时被中断的,创建了 instance 但在 render 中报错的情况// In a resume, we'll already have an instance we can reuse.// 复用 instanceshouldUpdate=resumeMountClassInstance(workInProgress,Component,nextProps,renderExpirationTime,);}else{// 更新渲染shouldUpdate=updateClassInstance(current,workInProgress,Component,nextProps,renderExpirationTime,);}returnfinishClassComponent(current,workInProgress,Component,shouldUpdate,hasContext,renderExpirationTime,);}
constructClassInstance 创建实例
functionconstructClassInstance(workInProgress: Fiber,ctor: any,props: any,renderExpirationTime: ExpirationTime,): any{letisLegacyContextConsumer=false;letunmaskedContext=emptyContextObject;letcontext=null;constcontextType=ctor.contextType;// context 相关// ctor 就是 Reactelemnt.type 即声明组件的组件名,这里生成组件实例constinstance=newctor(props,context);// 初始化 stateconststate=(workInProgress.memoizedState=instance.state!==null&&instance.state!==undefined
? instance.state
: null);// 为 instance 添加 updater 为 classComponentUpdater,// 指定 workInProgress 的 stateNode 为当前instance// ReactInstanceMap map 对象, 给 instance._reactInternaleFiber 赋值当前 workInprogressadoptClassInstance(workInProgress,instance);// 创建实例时的警告,使用 getDerivedStateFromProps 不推荐设置 state 为 null// 使用了 getDerivedStateFromProps 或者getSnapshotBeforeUpdate, willXXXX 声明周期方法不会执行if(__DEV__){// ...}// Cache unmasked context so we can avoid recreating masked context unless necessary.// ReactFiberContext usually updates this cache but can't for newly-created instances.// context 相关if(isLegacyContextConsumer){cacheContext(workInProgress,unmaskedContext,context);}returninstance;}// adoptClassInstance 方法functionadoptClassInstance(workInProgress: Fiber,instance: any): void{instance.updater=classComponentUpdater;workInProgress.stateNode=instance;// The instance needs access to the fiber so that it can schedule updatesReactInstanceMap.set(instance,workInProgress);if(__DEV__){instance._reactInternalInstance=fakeInternalInstance;}}
mountClassInstance 挂载实例
functionmountClassInstance(workInProgress: Fiber,ctor: any,newProps: any,renderExpirationTime: ExpirationTime,): void{if(__DEV__){checkClassInstance(workInProgress,ctor,newProps);}constinstance=workInProgress.stateNode;instance.props=newProps;instance.state=workInProgress.memoizedState;instance.refs=emptyRefsObject;constcontextType=ctor.contextType;if(typeofcontextType==='object'&&contextType!==null){instance.context=readContext(contextType);}else{constunmaskedContext=getUnmaskedContext(workInProgress,ctor,true);instance.context=getMaskedContext(workInProgress,unmaskedContext);}if(__DEV__){// .... }// 初次渲染 updateUqueue 为 null,当有 setState 时 updateQueue 可能有多个 update ,需要调用 processUpdateQueue 更新 stateletupdateQueue=workInProgress.updateQueue;if(updateQueue!==null){processUpdateQueue(workInProgress,updateQueue,newProps,instance,renderExpirationTime,);// 更新 instance 上的 stateinstance.state=workInProgress.memoizedState;}// 新的声明周期,组件更新过程中调用,即拿到的是更新后的 stateconstgetDerivedStateFromProps=ctor.getDerivedStateFromProps;if(typeofgetDerivedStateFromProps==='function'){applyDerivedStateFromProps(workInProgress,ctor,getDerivedStateFromProps,newProps,);// 更新 stateinstance.state=workInProgress.memoizedState;}// In order to support react-lifecycles-compat polyfilled components,// Unsafe lifecycles should not be invoked for components using the new APIs.// 用了新的 API 则 willMount 不会执行if(typeofctor.getDerivedStateFromProps!=='function'&&typeofinstance.getSnapshotBeforeUpdate!=='function'&&(typeofinstance.UNSAFE_componentWillMount==='function'||typeofinstance.componentWillMount==='function')){// willMount 可能执行了 setState 因此需要执行 processUpdateQueue 来更新 statecallComponentWillMount(workInProgress,instance);// If we had additional state updates during this life-cycle, let's// process them now.updateQueue=workInProgress.updateQueue;if(updateQueue!==null){processUpdateQueue(workInProgress,updateQueue,newProps,instance,renderExpirationTime,);instance.state=workInProgress.memoizedState;}}// 如果有 didMount,标记 effect 为 update,在 commit 阶段时,表明组件是有 didmount 这个方法的,// 等到组件内容真正 mount 到 dom 上时,才能真正调用 didmount 这个方法,等到需要用的时候才会去调用if(typeofinstance.componentDidMount==='function'){workInProgress.effectTag|=Update;}}
processUpdateQueue 更新state
都是基于 queue.baseState 来计算新的 state 的,遍历 updateQueue 过程中会将每个 update 的更新优先级与当前更新优先级做对比,如果低于当前更新优先级则不执行
exportfunctionprocessUpdateQueue<State>(workInProgress: Fiber,queue: UpdateQueue<State>,
props: any,
instance: any,
renderExpirationTime: ExpirationTime,
): void {hasForceUpdate=false;// 保证 workInProgress 上的 updateQueue 是 clone 的 queue,防止直接修改 current上的 queuequeue=ensureWorkInProgressQueueIsAClone(workInProgress,queue);if(__DEV__){currentlyProcessingQueue=queue;}
// These values may change as we process the queue.
// 每次执行完 processUpdateQueue 都会把新的 state 赋值到 baseState 上
let newBaseState = queue.baseState;
let newFirstUpdate = null;
let newExpirationTime = NoWork;
// Iterate through the list of updates to compute the result.
let update = queue.firstUpdate;
let resultState = newBaseState;
while (update !== null) {// update的执行优先级constupdateExpirationTime=update.expirationTime;// 优先级低则不执行if(updateExpirationTime>renderExpirationTime){// This update does not have sufficient priority. Skip it.if(newFirstUpdate===null){// This is the first skipped update. It will be the first update in// the new list.// 此 update 就成为剩下的第一个待更新的newFirstUpdate=update;// Since this is the first update that was skipped, the current result// is the new base state.newBaseState=resultState;}// Since this update will remain in the list, update the remaining// expiration time.if(newExpirationTime===NoWork||newExpirationTime>updateExpirationTime){// 不更新则赋值为此 update 的过期时间
newExpirationTime =updateExpirationTime;}} else {// This update does have sufficient priority. Process it and compute// a new result.// 这次 update 要被执行, setState 的 update.tag -> UpdateState -> 计算新的 state// 如果为 forceUpdate 则更新全局变量 hasForceUpdate = trueresultState=getStateFromUpdate(workInProgress,queue,update,resultState,// prevState 为之前计算的 baseStateprops,instance,);// setState(fn ,callback) callback 为第二个参数,在 setState 之后执行constcallback=update.callback;if(callback!==null){// 标记 effect 在 commit 阶段,setState 更新完成之后执行workInProgress.effectTag|=Callback;// Set this to null, in case it was mutated during an aborted render.// 防止中断的 render 过程被修改update.nextEffect=null;// 保存链表结构if(queue.lastEffect===null){queue.firstEffect=queue.lastEffect=update;} else {queue.lastEffect.nextEffect=update;queue.lastEffect=update;}}}// 操作下一个 update// Continue to the next update.update=update.next;}// 同样的对 captureUpdate 执行更新操作// Separately, iterate though the list of captured updates.letnewFirstCapturedUpdate=null;update=queue.firstCapturedUpdate;while(update!==null){constupdateExpirationTime=update.expirationTime;if(updateExpirationTime>renderExpirationTime){// This update does not have sufficient priority. Skip it.if(newFirstCapturedUpdate===null){// This is the first skipped captured update. It will be the first// update in the new list.newFirstCapturedUpdate=update;// If this is the first update that was skipped, the current result is// the new base state.if(newFirstUpdate===null){newBaseState=resultState;}}// Since this update will remain in the list, update the remaining// expiration time.if(newExpirationTime===NoWork||newExpirationTime>updateExpirationTime){
newExpirationTime =updateExpirationTime;}} else {// This update does have sufficient priority. Process it and compute// a new result.resultState=getStateFromUpdate(workInProgress,queue,update,resultState,props,instance,);constcallback=update.callback;if(callback!==null){workInProgress.effectTag|=Callback;// Set this to null, in case it was mutated during an aborted render.update.nextEffect=null;if(queue.lastCapturedEffect===null){queue.firstCapturedEffect=queue.lastCapturedEffect=update;} else {queue.lastCapturedEffect.nextEffect=update;queue.lastCapturedEffect=update;}}}update=update.next;}if(newFirstUpdate===null){queue.lastUpdate=null;}
if (newFirstCapturedUpdate === null) {queue.lastCapturedUpdate=null;} else {workInProgress.effectTag|=Callback;}
// 没有剩下来的 update,表示全部计算完了
if (newFirstUpdate === null &&newFirstCapturedUpdate===null){// We processed every update, without skipping. That means the new base// state is the same as the result state.// 重新赋值 newBaseState 为最后 计算的statenewBaseState=resultState;}
// 赋值 baseState 为计算后的 state
queue.baseState = newBaseState;
queue.firstUpdate = newFirstUpdate;
queue.firstCapturedUpdate = newFirstCapturedUpdate;
// Set the remaining expiration time to be whatever is remaining in the queue.
// This should be fine because the only two other things that contribute to
// expiration time are props and context. We're already in the middle of the
// begin phase by the time we start processing the queue, so we've already
// dealt with the props. Context in components that specify
// shouldComponentUpdate is tricky; but we'll have to account for
// that regardless.
// 需要执行的更新已经更新完了,剩下的更新应该是剩下的 updateQueue 里面的 update 中最高优先级的那个 expirationTime
workInProgress.expirationTime = newExpirationTime;
// 更新 state
workInProgress.memoizedState = resultState;
if (__DEV__) {currentlyProcessingQueue=null;}}
getStateFromUpdate 根据 setState 计算返回新的state
functiongetStateFromUpdate<State>(
workInProgress: Fiber,
queue: UpdateQueue<State>,
update: Update<State>,
prevState: State,
nextProps: any,
instance: any,
): any {switch(update.tag){caseReplaceState: {// ...}
case CaptureUpdate: {// ...}
// Intentional fallthrough
case UpdateState: {constpayload=update.payload;letpartialState;if(typeofpayload==='function'){// Updater functionif(__DEV__){// ...}// 函数更新 state
partialState =payload.call(instance,prevState,nextProps);}else{// 普通对象// Partial state object
partialState =payload;}if(partialState===null||partialState===undefined){// Null and undefined are treated as no-ops.
return prevState;}// Merge the partial state and the previous state.// 最后合并原 state 和计算出的新 statereturnObject.assign({},prevState,partialState);}
//
case ForceUpdate: {hasForceUpdate=true;returnprevState;}}returnprevState;}
applyDerivedStateFromProps 执行新声明周期钩子
exportfunctionapplyDerivedStateFromProps(workInProgress: Fiber,ctor: any,getDerivedStateFromProps: (props: any,state: any)=>any,nextProps: any,){// 这里的 state 是更新过后的stateconstprevState=workInProgress.memoizedState;// 传入的 state 是经过 processUpdateQueue 计算后的state constpartialState=getDerivedStateFromProps(nextProps,prevState);// Merge the partial state and the previous state.constmemoizedState=partialState===null||partialState===undefined
? prevState
: Object.assign({},prevState,partialState);// 更新stateworkInProgress.memoizedState=memoizedState;// Once the update queue is empty, persist the derived state onto the// base state.constupdateQueue=workInProgress.updateQueue;// queue 不为null 且 不渲染的时候,才更新 baseState if(updateQueue!==null&&workInProgress.expirationTime===NoWork){updateQueue.baseState=memoizedState;}}
resumeMountClassInstance 复用 instance 的情况
functionresumeMountClassInstance(workInProgress: Fiber,ctor: any,newProps: any,renderExpirationTime: ExpirationTime,): boolean{constinstance=workInProgress.stateNode;constoldProps=workInProgress.memoizedProps;instance.props=oldProps;constgetDerivedStateFromProps=ctor.getDerivedStateFromProps;consthasNewLifecycles=typeofgetDerivedStateFromProps==='function'||typeofinstance.getSnapshotBeforeUpdate==='function';// Note: During these life-cycles, instance.props/instance.state are what// ever the previously attempted to render - not the "current". However,// during componentDidUpdate we pass the "current" props.// In order to support react-lifecycles-compat polyfilled components,// Unsafe lifecycles should not be invoked for components using the new APIs.// 有新 API则不执行 componentWillReceivePropsif(!hasNewLifecycles&&(typeofinstance.UNSAFE_componentWillReceiveProps==='function'||typeofinstance.componentWillReceiveProps==='function')){if(oldProps!==newProps||oldContext!==nextContext){callComponentWillReceiveProps(workInProgress,instance,newProps,nextContext,);}}// => hasForceUpdate = falseresetHasForceUpdateBeforeProcessing();constoldState=workInProgress.memoizedState;letnewState=(instance.state=oldState);letupdateQueue=workInProgress.updateQueue;if(updateQueue!==null){processUpdateQueue(workInProgress,updateQueue,newProps,instance,renderExpirationTime,);newState=workInProgress.memoizedState;}if(// 新老 props 和 state 都相同oldProps===newProps&&oldState===newState&&// 没有 context 变化!hasContextChanged()&&// 如果 hasForceUpdate 为 false!checkHasForceUpdateAfterProcessing()){// If an update was already in progress, we should schedule an Update// effect even though we're bailing out, so that cWU/cDU are called.// 如果有 didMount 则标记 effect 为 updateif(typeofinstance.componentDidMount==='function'){workInProgress.effectTag|=Update;}// return 赋值给了 shouldUpdate, 组件是不需要更新的returnfalse;}// 执行新APIif(typeofgetDerivedStateFromProps==='function'){applyDerivedStateFromProps(workInProgress,ctor,getDerivedStateFromProps,newProps,);newState=workInProgress.memoizedState;}constshouldUpdate=// 如果 hasForceUpdate 为 truecheckHasForceUpdateAfterProcessing()||// 或者 根据 shouldComponentUpdate 的返回值 或者 pureComponent的情况则调用 shallowEqual 的返回值// 默认返回 truecheckShouldComponentUpdate(workInProgress,ctor,oldProps,newProps,oldState,newState,nextContext,);if(shouldUpdate){// 需要更新组件// In order to support react-lifecycles-compat polyfilled components,// Unsafe lifecycles should not be invoked for components using the new APIs.// 没有使用新声明周期并有 willMount 则调用 willMountif(!hasNewLifecycles&&(typeofinstance.UNSAFE_componentWillMount==='function'||typeofinstance.componentWillMount==='function')){startPhaseTimer(workInProgress,'componentWillMount');if(typeofinstance.componentWillMount==='function'){instance.componentWillMount();}if(typeofinstance.UNSAFE_componentWillMount==='function'){instance.UNSAFE_componentWillMount();}stopPhaseTimer();}if(typeofinstance.componentDidMount==='function'){workInProgress.effectTag|=Update;}// 都需要标记 didMount ,中断的组件挂载仍然按首次挂载执行}else{// 不需要更新// If an update was already in progress, we should schedule an Update// effect even though we're bailing out, so that cWU/cDU are called.if(typeofinstance.componentDidMount==='function'){workInProgress.effectTag|=Update;}// If shouldComponentUpdate returned false, we should still update the// memoized state to indicate that this work can be reused.// 组件不需要更新,仍然更新 memoized 变量workInProgress.memoizedProps=newProps;workInProgress.memoizedState=newState;}// Update the existing instance's state, props, and context pointers even// if shouldComponentUpdate returns false.// instance 上的 state、props、context 始终要更新instance.props=newProps;instance.state=newState;instance.context=nextContext;returnshouldUpdate;}
checkShouldComponentUpdate
functioncheckShouldComponentUpdate(workInProgress,ctor,oldProps,newProps,oldState,newState,nextContext,){constinstance=workInProgress.stateNode;// shouldComponentUpdate 来判断if(typeofinstance.shouldComponentUpdate==='function'){startPhaseTimer(workInProgress,'shouldComponentUpdate');constshouldUpdate=instance.shouldComponentUpdate(newProps,newState,nextContext,);stopPhaseTimer();returnshouldUpdate;}// 如果是pureComponent 则浅对比 props 和 stateif(ctor.prototype&&ctor.prototype.isPureReactComponent){return(!shallowEqual(oldProps,newProps)||!shallowEqual(oldState,newState));}returntrue;}// shallowEqualconsthasOwnProperty=Object.prototype.hasOwnProperty;/** * inlined Object.is polyfill to avoid requiring consumers ship their own * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is */// polyfill Object.is()functionis(x,y){// SameValue algorithmif(x===y){// Steps 1-5, 7-10// Steps 6.b-6.e: +0 != -0// Added the nonzero y check to make Flow happy, but it is redundantreturnx!==0||y!==0||1/x===1/y;}else{// Step 6.a: NaN == NaNreturnx!==x&&y!==y;}}/** * Performs equality by iterating through keys on an object and returning false * when any key has values which are not strictly equal between the arguments. * Returns true when the values of all keys are strictly equal. */functionshallowEqual(objA: mixed,objB: mixed): boolean{if(is(objA,objB)){returntrue;}if(typeofobjA!=='object'||objA===null||typeofobjB!=='object'||objB===null){returnfalse;}constkeysA=Object.keys(objA);constkeysB=Object.keys(objB);if(keysA.length!==keysB.length){returnfalse;}// Test for A's keys different from B.for(leti=0;i<keysA.length;i++){if(!hasOwnProperty.call(objB,keysA[i])||!is(objA[keysA[i]],objB[keysA[i]])){returnfalse;}}returntrue;}
if(shouldUpdate){// In order to support react-lifecycles-compat polyfilled components,// Unsafe lifecycles should not be invoked for components using the new APIs.// 未使用新API ,执行 componentWillUpdateif(!hasNewLifecycles&&(typeofinstance.UNSAFE_componentWillUpdate==='function'||typeofinstance.componentWillUpdate==='function')){startPhaseTimer(workInProgress,'componentWillUpdate');if(typeofinstance.componentWillUpdate==='function'){instance.componentWillUpdate(newProps,newState,nextContext);}if(typeofinstance.UNSAFE_componentWillUpdate==='function'){instance.UNSAFE_componentWillUpdate(newProps,newState,nextContext);}stopPhaseTimer();}// 标记 didUpdateif(typeofinstance.componentDidUpdate==='function'){workInProgress.effectTag|=Update;}// 标记 getSnapshotBeforeUpdateif(typeofinstance.getSnapshotBeforeUpdate==='function'){workInProgress.effectTag|=Snapshot;}}else{// If an update was already in progress, we should schedule an Update// effect even though we're bailing out, so that cWU/cDU are called.if(typeofinstance.componentDidUpdate==='function'){if(oldProps!==current.memoizedProps||oldState!==current.memoizedState){workInProgress.effectTag|=Update;}}if(typeofinstance.getSnapshotBeforeUpdate==='function'){if(oldProps!==current.memoizedProps||oldState!==current.memoizedState){workInProgress.effectTag|=Snapshot;}}// If shouldComponentUpdate returned false, we should still update the// memoized props/state to indicate that this work can be reused.workInProgress.memoizedProps=newProps;workInProgress.memoizedState=newState;}
functionfinishClassComponent(current: Fiber|null,workInProgress: Fiber,Component: any,shouldUpdate: boolean,hasContext: boolean,renderExpirationTime: ExpirationTime,){// 标记 ref,仅有在 classComponent 和 HostComponent (原生标签)中标记ref,即只能在这两种类型上 使用 ref// Refs should update even if shouldComponentUpdate returns falsemarkRef(current,workInProgress);constdidCaptureError=(workInProgress.effectTag&DidCapture)!==NoEffect;// 不需要更新且没有错误则跳过更新if(!shouldUpdate&&!didCaptureError){// Context providers should defer to sCU for renderingif(hasContext){invalidateContextProvider(workInProgress,Component,false);}// 跳过更新returnbailoutOnAlreadyFinishedWork(current,workInProgress,renderExpirationTime,);}constinstance=workInProgress.stateNode;// RerenderReactCurrentOwner.current=workInProgress;letnextChildren;if(didCaptureError&&typeofComponent.getDerivedStateFromError!=='function'){// getDerivedStateFromError 方法可以在出错后立即生成 state,防止出错后没有 instance 和 ref 的错误// 而 componentDidCatch 是通过 setState 的,要在下次更新才生成新的 state// 有错误,且没有 getDerivedStateFromError 方法 则直接渲染空// If we captured an error, but getDerivedStateFrom catch is not defined,// unmount all the children. componentDidCatch will schedule an update to// re-render a fallback. This is temporary until we migrate everyone to// the new API.// TODO: Warn in a future release.nextChildren=null;if(enableProfilerTimer){stopProfilerTimerIfRunning(workInProgress);}}else{// 没错误// 或者有 getDerivedStateFromError 方法,此方法已经更新了最新的state// 通过instance.render 获取最新childrenif(__DEV__){ReactCurrentFiber.setCurrentPhase('render');nextChildren=instance.render();if(debugRenderPhaseSideEffects||(debugRenderPhaseSideEffectsForStrictMode&&workInProgress.mode&StrictMode)){instance.render();}ReactCurrentFiber.setCurrentPhase(null);}else{nextChildren=instance.render();}}// React DevTools reads this flag.workInProgress.effectTag|=PerformedWork;// 非首次渲染且有错误if(current!==null&&didCaptureError){// If we're recovering from an error, reconcile without reusing any of// the existing children. Conceptually, the normal children and the children// that are shown on error are two different sets, so we shouldn't reuse// normal children even if their identities match.// 强制的重新计算 child 并 reconcileChildFibers 调和forceUnmountCurrentAndReconcile(current,workInProgress,nextChildren,renderExpirationTime,);}else{// 没错误或者首次渲染,直接调和reconcileChildren(current,workInProgress,nextChildren,renderExpirationTime,);}// Memoize state using the values we just used to render.// TODO: Restructure so we never read values from the instance.workInProgress.memoizedState=instance.state;// The context might have changed so we need to recalculate it.if(hasContext){invalidateContextProvider(workInProgress,Component,true);}// 返回 child -> performUnitOfWork -> workLoop 循环returnworkInProgress.child;}
The text was updated successfully, but these errors were encountered:
classComponent 更新 updateClassComponent
承担了唯二可以更新应用的api:
setState
、forceUpdate
首次渲染
instance
为null
constructClassInstance
创建实例mountClassInstance
挂载实例,调用willMount
getDerivedStateFromProps
则会执行并更新state
,并且不会执行willMount
钩子didMount
则标记workInProgress
的effectTag
为Update
渲染被中断
instance !== null
,current === null
resumeMountClassInstance
复用实例但还是调用首次渲染的生命周期方法getDerivedStateFromProps
则会执行并更新state
hasNewLifecycles
为true
, 则不会调用componentWillReceiveProps
和willMount
钩子,否则先调用componentWillReceiveProps
再调用componentWillMount
didMount
则标记workInProgress
的effectTag
为Update
更新渲染
instance !== null
,current !== nul
lupdateClassInstance
,调用componentWillReceiveProp
和willUpdate
生命周期getDerivedStateFromProps
则会执行并更新state
hasNewLifecycles
为true
则componentWillReceiveProp
和willUpdate
不会调用shouldUpdate
为true
,并有didUpdate
方法则标记workInProgress
的effectTag
为Update
初次渲染
updateUqueue
为null
,当有setState
时updateQueue
可能有多个update
,需要调用processUpdateQueue
更新state
最后执行
finishClassComponent
reconcileChildren
updateClassComponent
constructClassInstance 创建实例
mountClassInstance 挂载实例
processUpdateQueue 更新state
都是基于
queue.baseState
来计算新的state
的,遍历 updateQueue 过程中会将每个 update 的更新优先级与当前更新优先级做对比,如果低于当前更新优先级则不执行没有剩下来的 update 和 captureUpdate 表示全部计算完了,更新 baseState 为计算后的 resultState
getStateFromUpdate 根据 setState 计算返回新的state
applyDerivedStateFromProps 执行新声明周期钩子
resumeMountClassInstance 复用 instance 的情况
checkShouldComponentUpdate
updateClassInstance 更新渲染
resumeMountClassInstance
相似,不同的是执行的声明周期是willUpdate
,标记didUpdate
和getSnapshotBeforeUpdate
finishClassComponent 完成 class 组件更新
getDerivedStateFromError
方法,直接执行instance.render()
获得最新的nextChildren
, 否则nextChildren
为null
,getDerivedStateFromError
方法可以在出错后立即生成state
The text was updated successfully, but these errors were encountered: