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
// packages/react-reconciler/src/ReactFiberReconciler.new.jsexportfunctionupdateContainer(element: ReactNodeList,container: OpaqueRoot,parentComponent: ?React$Component<any,any>,callback: ?Function): Lane{if(__DEV__){onScheduleRoot(container,element);}constcurrent=container.current;consteventTime=requestEventTime();if(__DEV__){// $FlowExpectedError - jest isn't a global, and isn't recognized outside of testsif("undefined"!==typeofjest){warnIfUnmockedScheduler(current);warnIfNotScopedWithMatchingAct(current);}}constlane=requestUpdateLane(current);if(enableSchedulingProfiler){markRenderScheduled(lane);}constcontext=getContextForSubtree(parentComponent);if(container.context===null){container.context=context;}else{container.pendingContext=context;}if(__DEV__){if(ReactCurrentFiberIsRendering&&ReactCurrentFiberCurrent!==null&&!didWarnAboutNestedUpdates){didWarnAboutNestedUpdates=true;console.error("Render methods should be a pure function of props and state; "+"triggering nested component updates from render is not allowed. "+"If necessary, trigger nested updates in componentDidUpdate.\n\n"+"Check the render method of %s.",getComponentName(ReactCurrentFiberCurrent.type)||"Unknown");}}constupdate=createUpdate(eventTime,lane);// Caution: React DevTools currently depends on this property// being called "element".update.payload={ element };callback=callback===undefined ? null : callback;if(callback!==null){if(__DEV__){if(typeofcallback!=="function"){console.error("render(...): Expected the last optional `callback` argument to be a "+"function. Instead received: %s.",callback);}}update.callback=callback;}enqueueUpdate(current,update);scheduleUpdateOnFiber(current,lane,eventTime);returnlane;}
exportfunctionenqueueUpdate<State>(fiber: Fiber,update: Update<State>){// 存储执行中的更新任务 Update 队列,尾节点存储形式const updateQueue =fiber.updateQueue;if(updateQueue===null){// Only occurs if the fiber has been unmounted.
return;}//以 pending 属性存储待执行的更新任务 Update 队列,尾节点存储形式constsharedQueue: SharedQueue<State>=(updateQueue: any).shared;constpending=sharedQueue.pending;if(pending===null){// This is the first update. Create a circular list.// 第一次更新,创建一个循环列表
update.next=update;}else{update.next=pending.next;pending.next=update;}sharedQueue.pending=update;if(__DEV__){if(currentlyProcessingQueue===sharedQueue&&!didWarnUpdateInsideUpdate){console.error("An update (setState, replaceState, or forceUpdate) was scheduled "+"from inside an update function. Update functions should be pure, "+"with zero side-effects. Consider using componentDidUpdate or a "+"callback.");didWarnUpdateInsideUpdate=true;}}}
由上可以看出enqueueUpdate()函数主要是进行创建和更新UpdateQueue的操作。
The text was updated successfully, but these errors were encountered:
Update & UpdateQueue
创建了
RootFiber
对象和FiberRoot
对象之后,接下来就是处理更新。对应updateContainer
:可以看到通过
createUpdate()
函数创建出一个update
对象。首先需要明白
Update
对象到底是什么?它主要用于记录组件状态的改变,存放在UpdateQueue
中,通过计算得到一个最终的组件更新状态。同时多个Update
状态是可以同时存在的。下面是
createUpdate
函数所做的事情,其实就是包装了一层转换成了其他数据结构返回。其中
tag
属性对应四种情况,根据不同的情况执行不同的动作:这里顺便来看下
Update
对象:创建了
Update
对象后,将Update
对象传入enqueueUpdate()
,下面是enqueueUpdate()
所做的事情:由上可以看出
enqueueUpdate()
函数主要是进行创建和更新UpdateQueue
的操作。The text was updated successfully, but these errors were encountered: