2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Reactのstateはどのように推移するのか その3

Posted at

続き

ReactReconcileTransaction.js
function ReactReconcileTransaction(useCreateElement) {
  this.reinitializeTransaction();
  ...,
}

ここで各Transactionが初期化されている。
これが胡散臭い。

Transaction.js
var Mixin = {
  /**
   * Sets up this instance so that it is prepared for collecting metrics. Does
   * so such that this setup method may be used on an instance that is already
   * initialized, in a way that does not consume additional memory upon reuse.
   * That can be useful if you decide to make your subclass of this mixin a
   * "PooledClass".
   */
  reinitializeTransaction: function() {
    this.transactionWrappers = this.getTransactionWrappers();
    if (this.wrapperInitData) {
      this.wrapperInitData.length = 0;
    } else {
      this.wrapperInitData = [];
    }
    this._isInTransaction = false;
  },
};

getTransactionWrappersはthisがcontextなので、ReactReconcileTransactionを見る。

ReactReconcileTransaction.js
var Mixin = {
  getTransactionWrappers: function() {
    return TRANSACTION_WRAPPERS;
  },
}:
ReactReconcileTransaction.js
var SELECTION_RESTORATION = {
  /**
   * @return {Selection} Selection information.
   */
  initialize: ReactInputSelection.getSelectionInformation,
  /**
   * @param {Selection} sel Selection information returned from `initialize`.
   */
  close: ReactInputSelection.restoreSelection,
};

var EVENT_SUPPRESSION = {
  /**
   * @return {boolean} The enabled status of `ReactBrowserEventEmitter` before
   * the reconciliation.
   */
  initialize: function() {
    var currentlyEnabled = ReactBrowserEventEmitter.isEnabled();
    ReactBrowserEventEmitter.setEnabled(false);
    return currentlyEnabled;
  },

  /**
   * @param {boolean} previouslyEnabled Enabled status of
   *   `ReactBrowserEventEmitter` before the reconciliation occurred. `close`
   *   restores the previous value.
   */
  close: function(previouslyEnabled) {
    ReactBrowserEventEmitter.setEnabled(previouslyEnabled);
  },
};

var ON_DOM_READY_QUEUEING = {
  /**
   * Initializes the internal `onDOMReady` queue.
   */
  initialize: function() {
    this.reactMountReady.reset();
  },

  /**
   * After DOM is flushed, invoke all registered `onDOMReady` callbacks.
   */
  close: function() {
    this.reactMountReady.notifyAll();
  },
};

var TRANSACTION_WRAPPERS = [
  SELECTION_RESTORATION,
  EVENT_SUPPRESSION,
  ON_DOM_READY_QUEUEING,
];

ReactReconcileTransactionのmethodを呼び出すWrapperたち。
Wrapperというからには他のTransactionでも使われることを想定しているのだろうか。
最終的にwrapperInitData = []_isInTransaction = falseとなるだけのようだ。

つぎにちょっと飛んでTransaction.Mixin.performを見に行く。

Transaction.js
var Mixin = {
  perform: function(method, scope, a, b, c, d, e, f) {
    ...,
    this.initializeAll(0);
    ...,
  },
};

ここが怪しいので見てみる。

Transaction.js
var Mixin = {
  initializeAll: function(startIndex) {
    var transactionWrappers = this.transactionWrappers;
    for (var i = startIndex; i < transactionWrappers.length; i++) {
      var wrapper = transactionWrappers[i];
      try {
        this.wrapperInitData[i] = Transaction.OBSERVED_ERROR;
        this.wrapperInitData[i] = wrapper.initialize ?
          wrapper.initialize.call(this) :
          null;
      } finally {
        // エラー処理
      }
    }
  },
};

ここでTRANSACTION_WRAPPERSの各Wrapperのinializeが走る。
contextはthis=ReactReconcileTransaction

SELECTION_RESTORATION
initialize: ReactInputSelection.getSelectionInformation
ReactInputSelection.js
var ReactInputSelection = {
  ...,
  getSelectionInformation: function() {
    var focusedElem = getActiveElement();
    return {
      focusedElem: focusedElem,
      selectionRange:
          ReactInputSelection.hasSelectionCapabilities(focusedElem) ?
          ReactInputSelection.getSelection(focusedElem) :
          null,
    };
  },
};

ちなみにgetActiveElementはfacebookの内部Libraryになっている。
https://github.com/facebook/fbjs/blob/master/src/core/dom/getActiveElement.js

function getActiveElement() /*?DOMElement*/ {
  if (typeof document === 'undefined') {
    return null;
  }
  try {
    return document.activeElement || document.body;
  } catch (e) {
    return document.body;
  }
}

activeElementはこちらにある通り現在FocusされているDOMを取得する。

EVENT_SUPPRESSION
  initialize: function() {
    var currentlyEnabled = ReactBrowserEventEmitter.isEnabled();
    ReactBrowserEventEmitter.setEnabled(false);
    return currentlyEnabled;
  },

currentlyEnabledはtrueとなる。

ON_DOM_READY_QUEUEING
  initialize: function() {
    this.reactMountReady.reset();
  },

_callbacks=null_contexts=nullを得るだけ。

うーん。全然Queueを処理するような箇所が見当たらない・・

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?