Revert "Revert "Dispatch commands to both UIManagers from both renderers (#17211)" (#17232)" (#17799)
* Revert "Revert "Dispatch commands to both UIManagers from both renderers (#17211)" (#17232)" This reverts commit d0fc0ba0a688950b8ab24a89f14888a19efa2444. * Clean up another __DEV__ warning check
Eli White committed
Jan 7, 2020 at 16:47 UTC
19f6fe170ce920d7183a5620f4e218334c8bac62
3 files changed
+116
-27
packages/react-native-renderer/src/ReactFabric.js
+18
-17
@@ -29,6 +29,9 @@ import {createPortal} from 'shared/ReactPortal';
29
import {setBatchingImplementation} from 'legacy-events/ReactGenericBatching';
30
import ReactVersion from 'shared/ReactVersion';
31
32
+// Module provided by RN:
33
+import {UIManager} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
34
+
35
import NativeMethodsMixin from './NativeMethodsMixin';
36
import ReactNativeComponent from './ReactNativeComponent';
37
import {getClosestInstanceFromNode} from './ReactFabricComponentTree';
@@ -38,8 +41,6 @@ import {LegacyRoot} from 'shared/ReactRootTags';
41
import ReactSharedInternals from 'shared/ReactSharedInternals';
42
import getComponentName from 'shared/getComponentName';
43
41
-const {dispatchCommand: fabricDispatchCommand} = nativeFabricUIManager;
42
-
44
const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
45
46
function findHostInstance_DEPRECATED(
@@ -162,26 +163,26 @@ const ReactFabric: ReactFabricType = {
163
findNodeHandle,
164
165
dispatchCommand(handle: any, command: string, args: Array<any>) {
165
- const invalid =
166
- handle._nativeTag == null || handle._internalInstanceHandle == null;
167
-
168
- if (invalid) {
166
+ if (handle._nativeTag == null) {
167
if (__DEV__) {
170
- if (invalid) {
171
- console.error(
172
- "dispatchCommand was called with a ref that isn't a " +
173
- 'native component. Use React.forwardRef to get access to the underlying native component',
174
- );
175
- }
168
+ console.error(
169
+ "dispatchCommand was called with a ref that isn't a " +
170
+ 'native component. Use React.forwardRef to get access to the underlying native component',
171
+ );
172
}
173
+
174
return;
175
}
176
180
- fabricDispatchCommand(
181
- handle._internalInstanceHandle.stateNode.node,
182
- command,
183
- args,
184
- );
177
+ if (handle._internalInstanceHandle) {
178
+ nativeFabricUIManager.dispatchCommand(
179
+ handle._internalInstanceHandle.stateNode.node,
180
+ command,
181
+ args,
182
+ );
183
+ } else {
184
+ UIManager.dispatchViewManagerCommand(handle._nativeTag, command, args);
185
+ }
186
},
187
188
render(element: React$Element<any>, containerTag: any, callback: ?Function) {
packages/react-native-renderer/src/ReactNativeRenderer.js
+13
-7
@@ -174,17 +174,23 @@ const ReactNativeRenderer: ReactNativeType = {
174
dispatchCommand(handle: any, command: string, args: Array<any>) {
175
if (handle._nativeTag == null) {
176
if (__DEV__) {
177
- if (handle._nativeTag == null) {
178
- console.error(
179
- "dispatchCommand was called with a ref that isn't a " +
180
- 'native component. Use React.forwardRef to get access to the underlying native component',
181
- );
182
- }
177
+ console.error(
178
+ "dispatchCommand was called with a ref that isn't a " +
179
+ 'native component. Use React.forwardRef to get access to the underlying native component',
180
+ );
181
}
182
return;
183
}
184
187
- UIManager.dispatchViewManagerCommand(handle._nativeTag, command, args);
185
+ if (handle._internalInstanceHandle) {
186
+ nativeFabricUIManager.dispatchCommand(
187
+ handle._internalInstanceHandle.stateNode.node,
188
+ command,
189
+ args,
190
+ );
191
+ } else {
192
+ UIManager.dispatchViewManagerCommand(handle._nativeTag, command, args);
193
+ }
194
},
195
196
render(element: React$Element<any>, containerTag: any, callback: ?Function) {
packages/react-native-renderer/src/__tests__/ReactFabricAndNative-test.internal.js
+85
-3
@@ -16,7 +16,7 @@ let ReactNative;
16
let UIManager;
17
let createReactNativeComponentClass;
18
19
-describe('ReactFabric', () => {
19
+describe('created with ReactFabric called with ReactNative', () => {
20
beforeEach(() => {
21
jest.resetModules();
22
require('react-native/Libraries/ReactPrivate/InitializeNativeFabricUIManager');
@@ -75,7 +75,7 @@ describe('ReactFabric', () => {
75
});
76
77
it('dispatches commands on Fabric nodes with the RN renderer', () => {
78
- UIManager.dispatchViewManagerCommand.mockReset();
78
+ nativeFabricUIManager.dispatchCommand.mockClear();
79
const View = createReactNativeComponentClass('RCTView', () => ({
80
validAttributes: {title: true},
81
uiViewClassName: 'RCTView',
@@ -84,13 +84,95 @@ describe('ReactFabric', () => {
84
let ref = React.createRef();
85
86
ReactFabric.render(<View title="bar" ref={ref} />, 11);
87
- expect(UIManager.dispatchViewManagerCommand).not.toBeCalled();
87
+ expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled();
88
ReactNative.dispatchCommand(ref.current, 'myCommand', [10, 20]);
89
+ expect(nativeFabricUIManager.dispatchCommand).toHaveBeenCalledTimes(1);
90
+ expect(nativeFabricUIManager.dispatchCommand).toHaveBeenCalledWith(
91
+ expect.any(Object),
92
+ 'myCommand',
93
+ [10, 20],
94
+ );
95
+ expect(UIManager.dispatchViewManagerCommand).not.toBeCalled();
96
+ });
97
+});
98
+
99
+describe('created with ReactNative called with ReactFabric', () => {
100
+ beforeEach(() => {
101
+ jest.resetModules();
102
+ require('react-native/Libraries/ReactPrivate/InitializeNativeFabricUIManager');
103
+ ReactFabric = require('react-native-renderer/fabric');
104
+ jest.resetModules();
105
+ UIManager = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface')
106
+ .UIManager;
107
+ jest.mock('shared/ReactFeatureFlags', () =>
108
+ require('shared/forks/ReactFeatureFlags.native-oss'),
109
+ );
110
+ ReactNative = require('react-native-renderer');
111
+
112
+ React = require('react');
113
+ createReactNativeComponentClass = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface')
114
+ .ReactNativeViewConfigRegistry.register;
115
+ });
116
+
117
+ it('find Paper instances with the Fabric renderer', () => {
118
+ const View = createReactNativeComponentClass('RCTView', () => ({
119
+ validAttributes: {title: true},
120
+ uiViewClassName: 'RCTView',
121
+ }));
122
+
123
+ let ref = React.createRef();
124
+
125
+ class Component extends React.Component {
126
+ render() {
127
+ return <View title="foo" />;
128
+ }
129
+ }
130
+
131
+ ReactNative.render(<Component ref={ref} />, 11);
132
+
133
+ let instance = ReactFabric.findHostInstance_DEPRECATED(ref.current);
134
+ expect(instance._nativeTag).toBe(3);
135
+ });
136
+
137
+ it('find Paper nodes with the Fabric renderer', () => {
138
+ const View = createReactNativeComponentClass('RCTView', () => ({
139
+ validAttributes: {title: true},
140
+ uiViewClassName: 'RCTView',
141
+ }));
142
+
143
+ let ref = React.createRef();
144
+
145
+ class Component extends React.Component {
146
+ render() {
147
+ return <View title="foo" />;
148
+ }
149
+ }
150
+
151
+ ReactNative.render(<Component ref={ref} />, 11);
152
+
153
+ let handle = ReactFabric.findNodeHandle(ref.current);
154
+ expect(handle).toBe(3);
155
+ });
156
+
157
+ it('dispatches commands on Paper nodes with the Fabric renderer', () => {
158
+ UIManager.dispatchViewManagerCommand.mockReset();
159
+ const View = createReactNativeComponentClass('RCTView', () => ({
160
+ validAttributes: {title: true},
161
+ uiViewClassName: 'RCTView',
162
+ }));
163
+
164
+ let ref = React.createRef();
165
+
166
+ ReactNative.render(<View title="bar" ref={ref} />, 11);
167
+ expect(UIManager.dispatchViewManagerCommand).not.toBeCalled();
168
+ ReactFabric.dispatchCommand(ref.current, 'myCommand', [10, 20]);
169
expect(UIManager.dispatchViewManagerCommand).toHaveBeenCalledTimes(1);
170
expect(UIManager.dispatchViewManagerCommand).toHaveBeenCalledWith(
171
expect.any(Number),
172
'myCommand',
173
[10, 20],
174
);
175
+
176
+ expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled();
177
});
178
});