React中replaceProps的事务机制

最近在阅读React的源代码,在ReactComponent的replaceProps函数中,有一段事务机制的代码。


replaceProps: function(props) {
      invariant(
        !this.props[OWNER],
        'replaceProps(...): You called `setProps` or `replaceProps` on a ' +
        'component with an owner. This is an anti-pattern since props will ' +
        'get reactively updated when rendered. Instead, change the owner\'s ' +
        '`render` method to pass the correct value as props to the component ' +
        'where it is created.'
      );
      var transaction = ReactComponent.ReactReconcileTransaction.getPooled();
      transaction.perform(this.receiveProps, this, props, transaction);
      ReactComponent.ReactReconcileTransaction.release(transaction);
    },

在这段代码中,首先从事务池中取出了一个可用的transaction(事务池机制另附文讲述),然后在事务中执行了this.receiveProps,最后释放了事务。

这里的Transaction是借用的数据库中事务锁的概念。由于在更新props时,为了保证数据一致性,需要暂时切断其他可能对数据造成的影响,保证this.receiveProps的过程中,数据不被改变,这就如同数据库中的事务机制一般。那具体是如何实现的呢?

奥妙就在ReactReconcileTransaction中。ReactReconcileTransaction具有Transaction的mixin,在Transaction的源代码中,给出了其工作原理的解释:在perform方法执行之前,所有wrappers会依次先执行initialize(通常都是一些“上锁”的操作),并将执行结果保存在wrapperInitData数组中,然后在执行perform;而等到perform结束之后,又会按照wrappers的顺序逐一的执行close方法(解锁,上锁时存储的InitData也会被作为解锁的参数传递给close方法)。

具体到ReactReconcileTransaction,它在执行事务前,进行了如下的一些措施,保证数据的一致性:

  • 将当前选中区域的信息保存
  • 将事件监听暂停
  • 将ReactOnDomReady的数组清空

而当事务执行完毕后,需要恢复(解锁),又会进行相应的操作:

  • 恢复选区信息
  • 将事件监听状态恢复成原来的值(原来也可能不监听)
  • 通知onDomReady队列中的组建执行回调,并清空队列

通过这样的事务机制,保证了props数据在更新过程中的数据一致性。

Show Comments

Get the latest posts delivered right to your inbox.