ReactUpdates源码(待定)

本文详细解析了 React 中组件更新的流程,包括如何利用 ReactUpdates 模块来管理组件的更新队列,以及如何通过 ReactReconcileTransaction 和 ReactUpdatesFlushTransaction 实现组件更新前后的方法调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值