ReactUpdates模块约定组件重绘过程的前后钩子,包含ReactReconcileTransaction模块的前后钩子(可添加componentDidUpdate回调,及向组件提供updater参数,以使setState等方法可用),以及本模块ReactUpdatesFlushTransaction函数设定的前后钩子(可添加组件重绘完成后的回调callback);通过ReactUpdates.ReactReconcileTransaction提供ReactReconcileTransaction模块的接口;通过ReactUpdates.enqueueUpdate调用ReactDefaultBatchingStrategy模块,用于添加脏组件或触发重绘;通过ReactUpdates.batchedUpdates(fn)执行fn函数,并触发重绘等。
'use strict'; var _prodInvariant = require('./reactProdInvariant'),// 生产环境React形式带url报错 _assign = require('object-assign'); // 原型继承Transaction的某构造函数的实例将拥有perform(method,args)方法 // 实现功能为,method函数执行前后,调用成对的前置钩子initialize、及后置钩子close;initialize为close提供参数 var CallbackQueue = require('./CallbackQueue'); // PooledClass.addPoolingTo(CopyConstructor)用于将构造函数CopyConstructor转化为工厂函数 // 意义是管理实例数据的创建和销毁,并将销毁数据的实例推入到实例池CopyConstructor.instancePool中 var PooledClass = require('./PooledClass'); var ReactFeatureFlags = require('./ReactFeatureFlags'); var ReactReconciler = require('./ReactReconciler'); // 原型继承Transaction的某构造函数的实例将拥有perform(method,args)方法 // 实现功能为,method函数执行前后,调用成对的前置钩子initialize、及后置钩子close;initialize为close提供参数 var Transaction = require('./Transaction'); // invariant(condition,format,a,b,c,d,e,f) condition为否值,替换format中的"%s",并throw error报错 var invariant = require('fbjs/lib/invariant'); var dirtyComponents = []; var updateBatchNumber = 0; var asapCallbackQueue = CallbackQueue.getPooled(); var asapEnqueued = false; var batchingStrategy = null; // 确认ReactUpdates.ReactReconcileTransaction、batchingStrategy已添加 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; } // 组件更新前置钩子,将this.dirtyComponentsLength置为dirtyComponents中脏组件的个数 // 组件更新后置钩子,重绘过程中添加脏组件,调用flushBatchedUpdates重绘新添加的脏组件 // 重绘过程中没有添加脏组件,dirtyComponents清空 var NESTED_UPDATES = { initialize: function () { this.dirtyComponentsLength = dirtyComponents.length; }, close: function () { // 在组件重绘过程中,再度添加脏组件,剔除dirtyComponents中已重绘的组件,调用flushBatchedUpdates重绘新添加的脏组件 if (this.dirtyComponentsLength !== dirtyComponents.length) { dirtyComponents.splice(0, this.dirtyComponentsLength); flushBatchedUpdates(); } else { dirtyComponents.length = 0; } } }; // 通过CallbackQueue回调函数队列机制,即this.callbackQueue // 执行this.callbackQueue.enqueue(fn)注入组件更新完成后的回调callback,在runBatchedUpdates函数中实现 // 通过Transaction添加前、后置钩子机制 // 前置钩子initialize方法用于清空回调队列;close用于触发组件更新完成后的回调callback var UPDATE_QUEUEING = { initialize: function () { this.callbackQueue.reset(); }, close: function () { this.callbackQueue.notifyAll(); } }; var TRANSACTION_WRAPPERS = [NESTED_UPDATES, UPDATE_QUEUEING]; // 以特定钩子重绘dirtyComponents中的各组件,清空dirtyComponents,或调用flushBatchedUpdates重绘新添加的脏组件 // 钩子包括ReactUpdatesFlushTransaction前后钩子,可添加组件重绘完成后的回调_pendingCallbacks // 包括ReactReconcileTransaction前后钩子,可添加componentDidMount、componentDidUpdate回调 function ReactUpdatesFlushTransaction() { this.reinitializeTransaction();// 通过Transaction模块清空前后钩子 // 脏组件个数,用于更新dirtyComponents中待重绘的脏组件 this.dirtyComponentsLength = null; // this.callbackQueue用于存储组件更新完成后的回调 this.callbackQueue = CallbackQueue.getPooled(); // ReactReconcileTransaction实例 this.reconcileTransaction = ReactUpdates.ReactReconcileTransaction.getPooled(/* useCreateElement */true); } _assign(ReactUpdatesFlushTransaction.prototype, Transaction, { // 通过Transaction模块设定前置及后置钩子,[{initialize,close}]形式 getTransactionWrappers: function () { return TRANSACTION_WRAPPERS; }, // 清空ReactReconcileTransaction实例中的回调函数componentDidMount、componentDidUpdate // 清空CallbackQueue中的回调函数,再销毁this.reconcileTransaction destructor: function () { this.dirtyComponentsLength = null; CallbackQueue.release(this.callbackQueue); this.callbackQueue = null; ReactUpdates.ReactReconcileTransaction.release(this.reconcileTransaction); this.reconcileTransaction = null; }, // 间接调用ReactReconcileTransaction实例的perform方法执行method,method为当前模块的runBatchedUpdates函数 // method执行前后既会调用ReactReconcileTransaction设定的钩子,也会调用ReactUpdatesFlushTransaction设定的钩子 perform: function (method, scope, a) {// a为ReactReconcileTransaction实例 return Transaction.perform.call(this, this.reconcileTransaction.perform, this.reconcileTransaction, method, scope, a); } }); // 通过PooledClass模块管理实例的创建ReactUpdatesFlushTransaction.getPooled // 及实例数据的销毁ReactUpdatesFlushTransaction.release PooledClass.addPoolingTo(ReactUpdatesFlushTransaction); // ReactDefaultBatchingStrategy.isBatchingUpdates为否值时 // 执行callback回调,并调用flushBatchedUpdates重绘dirtyComponents中脏组件 // batchingStrategy.isBatchingUpdates为真值,只执行callback回调 function batchedUpdates(callback, a, b, c, d, e) { ensureInjected(); return batchingStrategy.batchedUpdates(callback, a, b, c, d, e); } // 比较组件的挂载顺序 function mountOrderComparator(c1, c2) { return c1._mountOrder - c2._mountOrder; } // 调用dirtyComponents中各组件的performUpdateIfNecessary以重绘该组件 // 并将该组件更新完成的回调_pendingCallbacks添加到ReactUpdatesFlushTransaction后置钩子中 function runBatchedUpdates(transaction) { var len = transaction.dirtyComponentsLength; // ReactUpdatesFlushTransaction中,前置钩子已将transaction.dirtyComponentsLength赋值为dirtyComponents.length // 再作校验,以确保 !(len === dirtyComponents.length) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected flush transaction\'s stored dirty-components length (%s) ' + 'to match dirty-components array length (%s).', len, dirtyComponents.length) : _prodInvariant('124', len, dirtyComponents.length) : void 0; // 以组件的挂载顺序排序 dirtyComponents.sort(mountOrderComparator); // 校验组件实例的component._updateBatchNumber同updateBatchNumber是否相等,一次只能更新一个组件 // 意义是重绘组件flushBatchedUpdates只能通过ReactUpdates.enqueueUpdate方法 // 即ReactDefaultBatchingStrategy.batchedUpdates方法进行重绘??? updateBatchNumber++; for (var i = 0; i < len; i++) { // 若组件尚未挂载,确保组件的performUpdateIfNecessary、_pendingCallbacks为空 var component = dirtyComponents[i]; var callbacks = component._pendingCallbacks; component._pendingCallbacks = null; var markerName; if (ReactFeatureFlags.logTopLevelRenders) { var namedComponent = component; // Duck type TopLevelWrapper. This is probably always true. if (component._currentElement.type.isReactTopLevelWrapper) { namedComponent = component._renderedComponent; } markerName = 'React update: ' + namedComponent.getName(); console.time(markerName); } // ReactReconciler.performUpdateIfNecessary间接调用component.performUpdateIfNecessary重绘组件 // transaction.reconcileTransaction即ReactReconcileTransaction实例 // 用于向组件提供updater参数,使setState等方法可用;以及挂载componentDidMount、componentDidUpdate回调 ReactReconciler.performUpdateIfNecessary(component, transaction.reconcileTransaction, updateBatchNumber); if (markerName) { console.timeEnd(markerName); } // 将组件更新完成后需要触发执行的callbacks回调函数添加到ReactUpdatesFlushTransaction后置钩子中 if (callbacks) { for (var j = 0; j < callbacks.length; j++) { transaction.callbackQueue.enqueue(callbacks[j], component.getPublicInstance()); } } } } // 以特定钩子重绘dirtyComponents中的各组件 // 钩子包括ReactUpdatesFlushTransaction前后钩子,含组件重绘完成后的回调_pendingCallbacks // 包括ReactReconcileTransaction前后钩子,含componentDidMount、componentDidUpdate回调 var flushBatchedUpdates = function () { while (dirtyComponents.length || asapEnqueued) { if (dirtyComponents.length) { // 获得ReactUpdatesFlushTransaction实例 var transaction = ReactUpdatesFlushTransaction.getPooled(); // 执行runBatchedUpdates // runBatchedUpdates函数调用dirtyComponents中各组件的performUpdateIfNecessary以重绘该组件 // 并将该组件更新完成的回调_pendingCallbacks添加到ReactUpdatesFlushTransaction后置钩子中 // 并执行ReactUpdatesFlushTransaction前后钩子,含组件重绘完成后的回调_pendingCallbacks // 并执行ReactReconcileTransaction前后钩子,含componentDidMount、componentDidUpdate回调 transaction.perform(runBatchedUpdates, null, transaction); // runBatchedUpdates及钩子函数执行完成,销毁ReactUpdatesFlushTransaction实例数据 ReactUpdatesFlushTransaction.release(transaction); } // ReactDefaultBatchingStrategy.batchedUpdates触发重绘时,执行asap方法添加的回调 if (asapEnqueued) { asapEnqueued = false; var queue = asapCallbackQueue; asapCallbackQueue = CallbackQueue.getPooled(); queue.notifyAll(); CallbackQueue.release(queue); } } }; // batchingStrategy.isBatchingUpdates即ReactDefaultBatchingStrategy.isBatchingUpdates为否值时 // 意味batchingStrategy.batchedUpdates不在执行中,添加脏组件并调用flushBatchedUpdates重绘 // batchingStrategy.isBatchingUpdates为真值,只向dirtyComponents中添加脏组件 function enqueueUpdate(component) { ensureInjected(); // batchingStrategy.isBatchingUpdates在batchingStrategy.batchedUpdates执行过程中为真,执行完成置否 // 通过Transition模块设置特定钩子实现,同时包含调用flushBatchedUpdates重绘脏组件的钩子 if (!batchingStrategy.isBatchingUpdates) { batchingStrategy.batchedUpdates(enqueueUpdate, component); return; } dirtyComponents.push(component); if (component._updateBatchNumber == null) { component._updateBatchNumber = updateBatchNumber + 1; } } // 挂载callback回调,ReactDefaultBatchingStrategy.batchedUpdates重绘机制触发时有效 // 也即用于挂载ReactDefaultBatchingStrategy.batchedUpdates方法重绘时的回调函数 function asap(callback, context) { // batchingStrategy.isBatchingUpdates即ReactDefaultBatchingStrategy.isBatchingUpdates为否值时 // ReactDefaultBatchingStrategy.batchedUpdates重绘机制未触发,报错 !batchingStrategy.isBatchingUpdates ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates.asap: ' + 'Can\'t enqueue an asap callback in a context whereupdates are not being batched.') : _prodInvariant('125') : void 0; asapCallbackQueue.enqueue(callback, context); asapEnqueued = true; } // 根据开发环境配置有所不同的注射器 // 其中ReactUpdates.ReactReconcileTransaction用于约定组件挂载前后的钩子函数,添加componentDidMount、componentDidUpdate回调 // 以及向组件构造函数传入updater参数,使setState、replaceState、forceUpdate方法可用 // batchingStrategy用途是??? var ReactUpdatesInjection = { // ReactDefaultInjection模块中,将ReactUpdates.ReactReconcileTransaction设定为ReactReconcileTransaction模块 injectReconcileTransaction: function (ReconcileTransaction) { !ReconcileTransaction ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a reconcile transaction class') : _prodInvariant('126') : void 0; ReactUpdates.ReactReconcileTransaction = ReconcileTransaction; }, // ReactDefaultInjection模块中,将batchingStrategy设定为为ReactDefaultBatchingStrategy模块 injectBatchingStrategy: function (_batchingStrategy) { !_batchingStrategy ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a batching strategy') : _prodInvariant('127') : void 0; !(typeof _batchingStrategy.batchedUpdates === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a batchedUpdates() function') : _prodInvariant('128') : void 0; !(typeof _batchingStrategy.isBatchingUpdates === 'boolean') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide an isBatchingUpdates boolean attribute') : _prodInvariant('129') : void 0; batchingStrategy = _batchingStrategy; } }; var ReactUpdates = { // 默认为ReactReconcileTransaction模块 // 实现功能为在mountComponentIntoNode函数调用指定的钩子函数,包括用户配置的componentDidMount、componentDidUpdate回调 // 使用方式为getPooled方法创建实例,release方法销毁实例数据 // perform方法执行mountComponentIntoNode函数,及前后钩子函数 // getReactMountReady().enqueue(fn)添加用户配置的componentDidMount、componentDidUpdate回调 // getReactMountReady().checkpoint()方法获取回调个数 // getReactMountReady().rollback(checkpoint)将回调个数设为checkpoint // 另一实现功能为向组件实例注入updater参数,将向setState、replaceState、forceUpdate方法提供函数功能 ReactReconcileTransaction: null, // ReactDefaultBatchingStrategy.isBatchingUpdates为否值时 // 执行callback回调,并调用flushBatchedUpdates重绘dirtyComponents中脏组件 // batchingStrategy.isBatchingUpdates为真值,只执行callback回调 batchedUpdates: batchedUpdates, // batchingStrategy.isBatchingUpdates即ReactDefaultBatchingStrategy.isBatchingUpdates为否值时 // 意味batchingStrategy.batchedUpdates不在执行中,添加脏组件并调用flushBatchedUpdates重绘 // batchingStrategy.isBatchingUpdates为真值,只向dirtyComponents中添加脏组件 enqueueUpdate: enqueueUpdate, // 以特定钩子重绘dirtyComponents中的各组件 // 钩子包括ReactUpdatesFlushTransaction前后钩子,含组件重绘完成后的回调_pendingCallbacks // 包括ReactReconcileTransaction前后钩子,含componentDidMount、componentDidUpdate回调 flushBatchedUpdates: flushBatchedUpdates, // 通过ReactInjection模块输出接口,ReactDefaultInjection模块添加指定的ReactReconcileTransaction、batchingStrategy // 其中,ReactUpdates.ReactReconcileTransaction默认为ReactReconcileTransaction模块 // batchingStrategy默认为ReactDefaultBatchingStrategy模块 injection: ReactUpdatesInjection, // 用于挂载ReactDefaultBatchingStrategy.batchedUpdates方法重绘时的回调函数 asap: asap }; module.exports = ReactUpdates;