摘要:接上文,流程圖臟組件從流程圖里能看出,會(huì)遍歷數(shù)組,并在事務(wù)中調(diào)用。該事務(wù)有兩個(gè)包裝器,和。對(duì)于這種情況,我們只能通過(guò)檢查批量更新的計(jì)數(shù)器來(lái)跳過(guò)這次更新。這個(gè)設(shè)計(jì)避免了同一個(gè)組件的重復(fù)更新。
接上文,
React流程圖:
https://bogdan-lyashenko.gith...
從流程圖里能看出,React會(huì)遍歷dirtyComponents數(shù)組,并在事務(wù)中調(diào)用ReactUpdates.runBatchedUpdates。這個(gè)事務(wù)是個(gè)新事務(wù)。那么為什么要這么設(shè)計(jì)呢?
此事務(wù)的類型為ReactUpdatesFlushTransaction,在此之前我們已經(jīng)提到過(guò),我們?nèi)タ聪缕湎鄳?yīng)的包裝器以方便我們理解這個(gè)事務(wù)具體完成什么任務(wù)。代碼里有如下注釋:
ReactUpdatesFlushTransaction包裝器會(huì)清空dirtyComponents數(shù)組,并且執(zhí)行所有已經(jīng)壓入隊(duì)列里的更新操作,這些操作一般都是由過(guò)程后的處理方法壓入的(比如,commponentDidUpdate方法)(ReactUpdatesFlushTransaction’s wrappers will clear the dirtyComponents array and perform any updates enqueued by mount-ready handlers (i.e., componentDidUpdate))
我們也驗(yàn)證下是否代碼真的這樣運(yùn)轉(zhuǎn)。該事務(wù)有兩個(gè)包裝器,NEST_UPDATES和UPDATE_QUEUEING。在事務(wù)的初始化階段,我們會(huì)先把dirtyComponentsLength存儲(chǔ)起來(lái),然后在關(guān)閉階段,React進(jìn)行組件比較。在更新過(guò)程中,很可能dirtyComponents組件都發(fā)生里改變,所以,需要不止一次的運(yùn)行flushBatchedUpdates方法。代碼比較直白,沒(méi)有什么黑魔法。
但是,這里其實(shí)有個(gè)地方需要注意下,ReactUpdatesFlushTransaction覆蓋了Transaction.perform方法,之所以這么做,是因?yàn)?,?zhí)行更新時(shí)需要調(diào)用ReactReconcileTransacation里的行為(這個(gè)事務(wù)在掛載過(guò)程中也使用到了,目的是為了確保應(yīng)用狀態(tài)安全)。所以,在ReactUpdatesFlushTransaction.perform方法的執(zhí)行過(guò)程中,ReactReconcileTransaction方法會(huì)被調(diào)用到,所以,就是把事務(wù)方法在包了一次。
整個(gè)技術(shù)流程大概如此:
[NESTED_UPDATES, UPDATE_QUEUEING].initialize() [SELECTION_RESTORATION, EVENT_SUPPRESSION, ON_DOM_READY_QUEUEING].initialize() method -> ReactUpdates.runBatchedUpdates [SELECTION_RESTORATION, EVENT_SUPPRESSION, ON_DOM_READY_QUEUEING].close() [NESTED_UPDATES, UPDATE_QUEUEING].close()
在此文的最后,我們會(huì)回到事務(wù)方法,在確認(rèn)下事務(wù)是如何幫助方法完成的,但在此之前,我們先確認(rèn)下ReactUpdates.runBatchedUpdates的實(shí)現(xiàn)。(srcrendererssharedstackreconcilerReactUpdates.js#125)
在執(zhí)行之前的第一步,就是把dirtyComponets進(jìn)行排序,如何排序呢?基于mount order這個(gè)字段進(jìn)行排序(一個(gè)整數(shù)值,在組件實(shí)例化時(shí)被設(shè)置進(jìn)組件),這個(gè)字段代表父組件(它們也最先掛載)先更新,子組件接下去更新,以此類推。下一步,React會(huì)對(duì)updateBatchNumber加1操作,這個(gè)字段類似于當(dāng)前處理DOM的ID,看下代碼里的注釋,看下代碼里的注釋:
在更新過(guò)程中加入隊(duì)列的更新必須在批量操作執(zhí)行完后再執(zhí)行。否則,假設(shè)dirtyComponents為有組件A,B,其中A的子組件為B,B有子組件C,如果C有更新,則B將再次被壓入隊(duì)列,導(dǎo)致B被更新兩次。對(duì)于這種情況,我們只能通過(guò)檢查批量更新的計(jì)數(shù)器來(lái)跳過(guò)這次更新。(‘Any updates enqueued while reconciling must be performed after this entire batch. Otherwise, if dirtyComponents is [A, B] where A has children B and C, B could update twice in a single batch if C’s render enqueues an update to B (since B would have already updated, we should skip it, and the only way we can know to do so is by checking the batch counter).’)
這個(gè)設(shè)計(jì)避免了同一個(gè)組件的重復(fù)更新。
最后,我們遍歷完整個(gè)dirtyComponents隊(duì)列,然后把每個(gè)組件傳遞給了ReactReconciler.performUpdateIfNecessary,這個(gè)方法會(huì)在ReactCompisteCompoent里被調(diào)用,所以,最終我們又回到了ReactCompsiteComponet里的updateComponet方法?,F(xiàn)在,我們可以更深入的研究下這個(gè)方法。
(未完待續(xù))
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/95909.html
摘要:技術(shù)上來(lái)說(shuō),當(dāng)方法被調(diào)用后或者發(fā)生改變后,方法都會(huì)被調(diào)用。下一步,會(huì)設(shè)置為。之后,檢測(cè)當(dāng)前更新是否由更新引起的。這是因?yàn)?,使用是?dǎo)致組件持久化更新,而會(huì)被方法的返回值重新賦值。 接上文, React流程圖:https://bogdan-lyashenko.gith... 更新組件 關(guān)于組件的更新,我們先看下代碼里的注釋: 對(duì)于已掛載組件的更新過(guò)程,React會(huì)首先調(diào)用component...
摘要:接上文,流程圖我們已經(jīng)知道掛載的工作流程,現(xiàn)在我們換個(gè)方向研究下方法,這個(gè)也是的重要組成部分。這個(gè)問(wèn)題,我們會(huì)在下一篇文章中進(jìn)行解答。。。 接上文, React流程圖:https://bogdan-lyashenko.gith... this.setState 我們已經(jīng)知道掛載的工作流程,現(xiàn)在我們換個(gè)方向研究下--setState方法,這個(gè)也是React的重要組成部分。 首先,為什么我...
摘要:源碼里有個(gè)獨(dú)立的模塊管理組件的所有子元素。第一個(gè),實(shí)例化子元素使用并掛載它們。至于具體掛載流程,基于子元素類型的不同而有不同的掛載過(guò)程。掛載的過(guò)程基本完成了。 接上文, React流程圖:https://bogdan-lyashenko.gith... 創(chuàng)建初始子組件 在之前的步驟里,組件本身的構(gòu)建已經(jīng)完成,接下去,我們分析它們的子元素??偣卜譃閮刹剑簰燧d子元素(this.mountC...
摘要:當(dāng)鼠標(biāo)事件發(fā)生時(shí),組件的最外層會(huì)進(jìn)行處理,然后通過(guò)幾層包裝器的處理后,會(huì)開始進(jìn)行批量更新操作。在這之后,會(huì)將這些事件處理成常見到樣子。 接上文, React流程圖:https://bogdan-lyashenko.gith... 回到最初 在流程圖中,也許你已經(jīng)注意到,setState方法可以通過(guò)幾種方式觸發(fā),更準(zhǔn)確的說(shuō),可以分為是否由外部引起的(也就是是否由用戶觸發(fā))。讓我們看下如下...
摘要:接著,將返回的元素和之前的進(jìn)行比較的,以驗(yàn)證是否真的需要更新。我們看下代碼,代碼比較簡(jiǎn)單好,對(duì)應(yīng)于我們的這個(gè)列子,我們對(duì)于方法的更改并不會(huì)對(duì)方法造成影響。所以我們進(jìn)入下一步,也就是對(duì)于節(jié)點(diǎn)的更新。 接上文, React流程圖:https://bogdan-lyashenko.gith... 如果組件真的需要更新 在組件剛開始更新過(guò)程時(shí),如果有定義componentWillUpdate方...
閱讀 655·2021-11-25 09:43
閱讀 1928·2021-11-17 09:33
閱讀 842·2021-09-07 09:58
閱讀 2075·2021-08-16 10:52
閱讀 494·2019-08-30 15:52
閱讀 1736·2019-08-30 15:43
閱讀 1015·2019-08-30 15:43
閱讀 2938·2019-08-29 16:41