上篇博客介紹了
instantiateReactComponent
方法,方法內部實現(xiàn)還是很簡單的,那么回到react得渲染流程里冠王,接下來就是執(zhí)行ReactUpdates.batchedUpdates
方法向挖,所以本篇博客講解ReactUpdates
操作,從名字可以看出這是處理React更新的文件哪替,內部用到一個很重要得東西就是Transaction
栋荸,對于這個詞想必大家還是很熟悉得。ReactUpdates
內部實現(xiàn)也是很簡單,內部封裝了batchedUpdates
蒸其,enqueueUpdate
敏释,flushBatchedUpdates
等方法,而這三個是最重要的操作摸袁。內部也用到了一些全局依賴注入得東西钥顽,和上一篇博客提到的是一樣的。
ReactUpdates
var ReactUpdates = {
/**
* React references `ReactReconcileTransaction` using this property in order
* to allow dependency injection.
*
* @internal
*/
ReactReconcileTransaction: null,
batchedUpdates: batchedUpdates,
enqueueUpdate: enqueueUpdate,
flushBatchedUpdates: flushBatchedUpdates,
injection: ReactUpdatesInjection,
asap: asap
};
這是最終的ReactUpdates
對象靠汁,內部得屬性還是很少的蜂大,這邊的asap
不做說明,我沒看懂這個東西蝶怔,還望各位大牛指導奶浦!,下面就一一為這些屬性說明
ReactUpdates.injection
將injection
放在第一個是因為踢星,這個方法在全局以來注入的時候就被執(zhí)行了澳叉,論執(zhí)行順序的話,這個方法是第一個被執(zhí)行的方法沐悦,而且下面的方法需要用到依賴注入的東西成洗,本著不讓看官不知道這個變量是從哪里來的原則,所以這個方法放在第一位藏否。
injection
對應著ReactUpdatesInjection
// ReactUpdates.js
var ReactUpdatesInjection = {
injectReconcileTransaction: function (ReconcileTransaction) {
!ReconcileTransaction ? /**/
ReactUpdates.ReactReconcileTransaction = ReconcileTransaction;
},
injectBatchingStrategy: function (_batchingStrategy) {
!_batchingStrategy ? /**/
batchingStrategy = _batchingStrategy;
}
};
內部有兩個函數(shù)瓶殃,分別用于給ReactUpdates.ReactReconcileTransaction
和 外部閉包的batchingStrategy
變量賦值。每個函數(shù)內部都會首先對傳入的參數(shù)做一個是否存在的驗證副签。那么來看傳遞的實參是什么遥椿,回到ReactDefaultInjection.js
文件
// ReactDefaultInjection.js
ReactInjection.Updates.injectReconcileTransaction(ReactReconcileTransaction);
ReactInjection.Updates.injectBatchingStrategy(ReactDefaultBatchingStrategy);
那么這邊可以看到一個是ReactReconcileTransaction
對象,一個是ReactDefaultBatchingStrategy
對象淆储,這兩個都是重點冠场。拿起小筆開始畫重點了!6艨肌慈鸠!依舊留坑,以后會說的灌具。本人是講信用的人青团,你看這兩篇博客不就是在填坑。
ReactUpdates.ReactReconcileTransaction
ReactReconcileTransaction
屬性是全局依賴注入通過ReactUpdates.injection.injectReconcileTransaction
方法完成賦值操作咖楣。
該屬性翻譯為中文就是 ‘React 調和事務’督笆。這邊reconcile
調和調節(jié)得意思,實質上就是一個過程诱贿,state改變導致VDom改變娃肿,然后計算真實Dom的過程咕缎。這邊用到了Transaction
將在下一篇博客進行講解。并將React中得各個Transaction衍生而來得自定義Transaction做一個總結料扰。
ReactUpdates.batchedUpdates
batchedUpdates
翻譯為中文就是‘批量更新’凭豪,大家都知道在React中,setState
方法是批處理的晒杈。這也是為什么React會渲染很快的原因嫂伞,內部的更新進行批處理操作,避免不必要的渲染拯钻。
function batchedUpdates(callback, a, b, c, d, e) {
ensureInjected();
return batchingStrategy.batchedUpdates(callback, a, b, c, d, e);
}
這邊首先執(zhí)行一個ensureInjected()
方法帖努,目的是確保之前依賴注入的兩個變量都完成了注入。
function ensureInjected() {
!(ReactUpdates.ReactReconcileTransaction && batchingStrategy)
? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must inject a reconcile transaction class and batching strategy')
: _prodInvariant('123') : void 0;
}
順便一提粪般,這邊有一個小東西 void 0
拼余,在我的博客網(wǎng)站有做過說明,附上傳送門void (0) ??? undefined
那么回到正題亩歹,這個方法本質上是調用的batchingStrategy.batchedUpdates(callback, a, b, c, d, e)
匙监,這邊的batchingStrategy
就是一開始依賴注入的ReactDefaultBatchingStrategy
,是React的默認批處理策略捆憎。下一片博客的主題就是這個舅柜。
ReactUpdates.flushBatchedUpdates
這邊提到一個對象叫dirtyComponents
,因為還沒有用到躲惰,所以這邊只是大概的描述一下,在你的React中变抽,當你調用setState
時础拨,React會將你傳入的值壓倒一個隊列中,然后將該組件標記為一個dirtyComponent
绍载,最后會回過頭來查看這個更新隊列诡宗,遍歷隊列計算出最終的值,然后進行渲染击儡,這樣就達到了批處理的操作塔沃,避免了大量不必要的渲染。
那么這邊用到了一個ReactUpdatesFlushTransaction
‘更新刷新事務’
var flushBatchedUpdates = function () {
// ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents
// array and perform any updates enqueued by mount-ready handlers (i.e.,
// componentDidUpdate) but we need to check here too in order to catch
// updates enqueued by setState callbacks and asap calls.
while (dirtyComponents.length || asapEnqueued) {
if (dirtyComponents.length) {
var transaction = ReactUpdatesFlushTransaction.getPooled();
transaction.perform(runBatchedUpdates, null, transaction);
ReactUpdatesFlushTransaction.release(transaction);
}
if (asapEnqueued) {
asapEnqueued = false;
var queue = asapCallbackQueue;
asapCallbackQueue = CallbackQueue.getPooled();
queue.notifyAll();
CallbackQueue.release(queue);
}
}
};
ReactUpdates.asap
不知道是個啥東西阳谍。蛀柴。。
/**
* Enqueue a callback to be run at the end of the current batching cycle. Throws
* if no updates are currently being performed.
* 在當前批處理周期結束時運行回調矫夯。如果當前沒有執(zhí)行更新鸽疾,則引發(fā)。
*/
function asap(callback, context) {
invariant(batchingStrategy.isBatchingUpdates, "ReactUpdates.asap: Can't enqueue an asap callback in a context where" + 'updates are not being batched.');
asapCallbackQueue.enqueue(callback, context);
asapEnqueued = true;
}
總結
那么這邊是執(zhí)行ReactUpdates.batchedUpdates
训貌,它實質上是執(zhí)行的ReactDefaultBatchingStrategy.batchedUpdates
制肮,這樣我們的渲染流程到此就又加上一筆冒窍。
本篇留坑
Transaction 及尤其衍生出的自定義事務
ReactDefaultBatchingStrategy
下篇博客:ReactDefaultBatchingStrategy