Fix order of method execution in Fabric ViewManager

Summary:
Because of the changes made in Fabric, the order of the execution of some methods in ViewManager has changed. In Paper the following order was guaranteed: `createViewInstance -> addEventEmitters -> updateProperties -> onAfterUpdateTransaction`. But in Fabric, the order is the following: `createViewInstance -> updateProperties -> onAfterUpdateTransaction -> addEventEmitters`. This change can actually break some existing view managers, because they rely on the fact that `addEventEmitters` will be called before `onAfterUpdateTransaction`. Check ReactVideoManager:

```
ReactModule(name = ReactVideoManager.REACT_CLASS)
public class ReactVideoManager extends SimpleViewManager<ReactVideoPlayer>
    implements VideoManagerInterface<ReactVideoPlayer> {
...

  Override
  protected void onAfterUpdateTransaction(ReactVideoPlayer view) {
    super.onAfterUpdateTransaction(view);
    view.commitChanges();
  }

 Override
  protected void addEventEmitters(
      final ThemedReactContext reactContext, final ReactVideoPlayer view) {
    view.setStateChangedListener(
        new ReactVideoPlayer.PlayerStateChangedListener() {
...
}
```

As you can see there is a state change listener registered in `addEventEmitters` and `view.commitChanges()` can actually cause a state change. It means that if `onAfterUpdateTransaction` is executed before `addEventEmitters`, the state change listener will be added after a state change has happened and the event will be missed.

Reviewed By: JoshuaGross

Differential Revision: D17600308

fbshipit-source-id: 044e09e0d64973c8237876311d37c057a1ba384e
This commit is contained in:
Oleksandr Melnykov 2019-10-01 03:54:41 -07:00 коммит произвёл Facebook Github Bot
Родитель 36b7febe8f
Коммит b21a941923
1 изменённых файлов: 1 добавлений и 1 удалений

Просмотреть файл

@ -80,7 +80,6 @@ public abstract class ViewManager<T extends View, C extends ReactShadowNode>
@Nullable StateWrapper stateWrapper,
JSResponderHandler jsResponderHandler) {
T view = createViewInstance(reactContext, props, stateWrapper);
addEventEmitters(reactContext, view);
if (view instanceof ReactInterceptingViewGroup) {
((ReactInterceptingViewGroup) view).setOnInterceptTouchEventListener(jsResponderHandler);
}
@ -137,6 +136,7 @@ public abstract class ViewManager<T extends View, C extends ReactShadowNode>
@Nullable ReactStylesDiffMap initialProps,
@Nullable StateWrapper stateWrapper) {
T view = createViewInstance(reactContext);
addEventEmitters(reactContext, view);
if (initialProps != null) {
updateProperties(view, initialProps);
}