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

## 結論
InjectではReactUpdates.flushBatchedUpdatesが実行されている形跡はなかった

## inject追跡

もはやすべてのinjectを見るしか、queueの処理をつかめないので、頑張る。

```js:ReactDefaultInjection.js

function inject() {
  ...,

   // ReactBrowserEventEmitter.injection.injectReactEventListener(ReactEventListener)
   ReactInjection.EventEmitter.injectReactEventListener(
    ReactEventListener
  );

  ...,
}
```

```js:ReactBrowserEventEmitter.js
var ReactBrowserEventEmitter = assign({}, ReactEventEmitterMixin, {
  ReactEventListener: null,

  injection: {
    /**
     * @param {object} ReactEventListener
     */
    injectReactEventListener: function(ReactEventListener) {
      ReactEventListener.setHandleTopLevel(
        ReactBrowserEventEmitter.handleTopLevel
      );
      ReactBrowserEventEmitter.ReactEventListener = ReactEventListener;
    },
  },

  ...,
};
```

`ReactBrowserEventEmitter.ReactEventListener= ReactEventListener`となる。

```js:ReactEventListener.js
var ReactEventListener = {
   ...,
}
```

ここは外れ。次。

```js:ReactDefaultInjection.js

function inject() {
  ...,

  // EventPluginHub.injection.injectEventPluginOrder(DefaultEventPluginOrder)
  // = EventPluginRegistry.injectEventPluginOrder(DefaultEventPluginOrder)
  ReactInjection.EventPluginHub.injectEventPluginOrder(DefaultEventPluginOrder);
  
  ...,
}
```

```js:EventPluginHub.js
var EventPluginHub = {

  /**
   * Methods for injecting dependencies.
   */
  injection: {

    /**
     * @param {array} InjectedEventPluginOrder
     * @public
     */
    injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder,

    ...,

  },

  ...,

};
```

```js:EventPluginRegistry.js
var EventPluginRegistry = {
  ...,

  injectEventPluginOrder: function(InjectedEventPluginOrder) {
    ...,

    // Clone the ordering so it cannot be dynamically mutated.
    // 配列にコピーすることで元のobjectを壊さない
    // EventPluginOrder = [DefaultEventPluginOrder]
    EventPluginOrder = Array.prototype.slice.call(InjectedEventPluginOrder);
    recomputePluginOrdering();
  },

  ...,
};
```

```js:EventPluginRegistry.js
function recomputePluginOrdering() {
  if (!EventPluginOrder) {
    // Wait until an `EventPluginOrder` is injected.
    return;
  }

  for (var pluginName in namesToPlugins) {
    ..., // この時点ではないので無視

  }
}
```

ここも外れ。次。

```js:ReactDefaultInjection.js

function inject() {
  ...,

  // EventPluginUtils.injection.injectComponentTree(ReactDOMComponentTree)
  ReactInjection.EventPluginUtils.injectComponentTree(ReactDOMComponentTree);

  ...,
}
```

```js::EventPluginUtils.js
var injection = {
  injectComponentTree: function(Injected) {
    // ComponentTree = ReactDOMComponentTree
    ComponentTree = Injected;
    
    ...,
  },

  ...,
};
```

ここは外れ。次。

```js:ReactDefaultInjection.js

function inject() {
  ...,

  // EventPluginUtils.injection.injectTreeTraversal(ReactDOMTreeTraversal)
  ReactInjection.EventPluginUtils.injectTreeTraversal(ReactDOMTreeTraversal);

  ...,
}
```

```js::EventPluginUtils.js
var injection = {
  injectTreeTraversal: function(Injected) {
    // TreeTraversal = ReactDOMTreeTraversal
    TreeTraversal = Injected;
    
    ...,
  },

  ...,
};
```

ここも外れ・・。いつになれば・・。

```js:ReactDefaultInjection.js
function inject() {
  ...,

  ReactInjection.EventPluginHub.injectEventPluginsByName({
    SimpleEventPlugin: SimpleEventPlugin,
    EnterLeaveEventPlugin: EnterLeaveEventPlugin,
    ChangeEventPlugin: ChangeEventPlugin,
    SelectEventPlugin: SelectEventPlugin,
    BeforeInputEventPlugin: BeforeInputEventPlugin,
  });

  ...,
}
```

```js:EventPluginHub.js
var EventPluginHub = {

  /**
   * Methods for injecting dependencies.
   */
  injection: {
    ...,

    /**
     * @param {object} injectedNamesToPlugins Map from names to plugin modules.
     */
    injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName,
  },

  ...,

};
```

```js:EventPluginRegistry.js
var EventPluginRegistry = {
  ...,

  injectEventPluginsByName: function(injectedNamesToPlugins) {
    var isOrderingDirty = false;
    for (var pluginName in injectedNamesToPlugins) {
      // 何かのprototypeから継承してるものは無視
      if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
        continue;
      }
      var PluginModule = injectedNamesToPlugins[pluginName];
      // namesToPluginsに含まてれいない場合は追加
      if (!namesToPlugins.hasOwnProperty(pluginName) ||
          namesToPlugins[pluginName] !== PluginModule) {
        ...,

        namesToPlugins[pluginName] = PluginModule;
        isOrderingDirty = true;
      }
    }
    if (isOrderingDirty) {
      recomputePluginOrdering();
    }
  },

  ...,
};
```

```js:EventPluginRegistry.js
function recomputePluginOrdering() {
  if (!EventPluginOrder) {
    // Wait until an `EventPluginOrder` is injected.
    return;
  }

  for (var pluginName in namesToPlugins) {
    // さっき無視されたのがここで実行される
    var PluginModule = namesToPlugins[pluginName];
    var pluginIndex = EventPluginOrder.indexOf(pluginName);

    ...,

    if (EventPluginRegistry.plugins[pluginIndex]) {
      continue;
    }

    ...,

    EventPluginRegistry.plugins[pluginIndex] = PluginModule;
    var publishedEvents = PluginModule.eventTypes;
    for (var eventName in publishedEvents) {
      // エラー処理
    }
  }
}
```

```js:DefaultEventPluginOrder.js
// keyOfはfacebook内部のLibraryらしい
var DefaultEventPluginOrder = [
  keyOf({ResponderEventPlugin: null}),
  keyOf({SimpleEventPlugin: null}),
  keyOf({TapEventPlugin: null}),
  keyOf({EnterLeaveEventPlugin: null}),
  keyOf({ChangeEventPlugin: null}),
  keyOf({SelectEventPlugin: null}),
  keyOf({BeforeInputEventPlugin: null}),
];
```

ここも外れ。どこなんだ・・。

```js:ReactDefaultInjection.js

function inject() {
  ...,

  // DOMProperty.injection.injectDOMPorpertyConfig
  ReactInjection.DOMProperty.injectDOMPropertyConfig(HTMLDOMPropertyConfig);
  ReactInjection.DOMProperty.injectDOMPropertyConfig(SVGDOMPropertyConfig);

  ...,
}
```

いっぺんに見ていく。

```js:DOMProperty.js
var DOMPropertyInjection = {
  /**
   * Mapping from normalized, camelcased property names to a configuration that
   * specifies how the associated DOM property should be accessed or rendered.
   */
  MUST_USE_PROPERTY: 0x1,
  HAS_SIDE_EFFECTS: 0x2,
  HAS_BOOLEAN_VALUE: 0x4,
  HAS_NUMERIC_VALUE: 0x8,
  HAS_POSITIVE_NUMERIC_VALUE: 0x10 | 0x8,
  HAS_OVERLOADED_BOOLEAN_VALUE: 0x20,

  injectDOMPropertyConfig: function(domPropertyConfig) {
    
    ...,

  },
};
```

ここも外れ。とうとう最後・・

```js:ReactDefaultInjection.js

function inject() {
  ...,

  // ReactComponentEnvironment.injection.injectEnvironment(ReactComponentBrowserEnvironment)
  ReactInjection.Component.injectEnvironment(ReactComponentBrowserEnvironment);

  ...,
}
```

```js:ReactComponentEnvironment.js
var ReactComponentEnvironment = {
  injection: {
    injectEnvironment: function(environment) {
      ...,

      // environment = ReactComponentBrowserEnvironment
      ReactComponentEnvironment.unmountIDFromEnvironment =
        environment.unmountIDFromEnvironment;
      ReactComponentEnvironment.replaceNodeWithMarkup =
        environment.replaceNodeWithMarkup;
      ReactComponentEnvironment.processChildrenUpdates =
        environment.processChildrenUpdates;
      injected = true;
    },
  },
};
```

```js:ReactComponentBrowserEnvironment.js
var ReactComponentBrowserEnvironment = {
  processChildrenUpdates:
    ReactDOMIDOperations.dangerouslyProcessChildrenUpdates,

  replaceNodeWithMarkup:
    DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup,

  unmountIDFromEnvironment: function(rootNodeID) {
  },
};
```

```js:ReactDOMIDOperations.js
var ReactDOMIDOperations = {
  dangerouslyProcessChildrenUpdates: function(parentInst, updates) {
    var node = ReactDOMComponentTree.getNodeFromInstance(parentInst);
    DOMChildrenOperations.processUpdates(node, updates);
  },
}
```

```js:DOMChildrenOperations.js
var DOMChildrenOperations = {
  dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup,

  ...,

};
```

```js:Danger.js
var Danger = {
  ...,

  dangerouslyReplaceNodeWithMarkup: function(oldChild, markup) {
    ...,

    if (typeof markup === 'string') {
      var newChild = createNodesFromMarkup(markup, emptyFunction)[0];
      oldChild.parentNode.replaceChild(newChild, oldChild);
    } else {
      DOMLazyTree.replaceChildWithTree(oldChild, markup);
    }
  },
};
```

どちらもmethodを設定しているだけなので外れ。ナンテコッタイ！