ReactNative upstream sync (#9197)
* Addresses a circular dependency between NativeMethodsMixin and ReactNativeFiber: * Created new ReactNativeFiberHostComponent with similar interface but without unnecessary call to findNodeHandle. * Created new Flow interface for mixins to ensure ReactNativeFiberHostComponent and NativeMethodsMixinUtils stay synced. * Moved helper methods to NativeMethodsMixinUtils to be shared between the 2 wrappers. This diff was submitted and reviewed internally along with some other ReactNative changes. This is the React-only portion. * Removed unused Flow type import * Copied a Flow fix from internal
Brian Vaughn committed
Mar 20, 2017 at 13:50 UTC
7f665da0eee37383cd2b50c82f490170d2979e10
9 files changed
+388
-121
src/renderers/native/NativeMethodsMixin.js
+131
-83
@@ -12,50 +12,28 @@
12
'use strict';
13
14
var ReactNative = require('ReactNative');
15
+var ReactNativeFeatureFlags = require('ReactNativeFeatureFlags');
16
var ReactNativeAttributePayload = require('ReactNativeAttributePayload');
17
var TextInputState = require('TextInputState');
18
var UIManager = require('UIManager');
19
20
var invariant = require('fbjs/lib/invariant');
21
+var findNodeHandle = require('findNodeHandle');
22
21
-type MeasureOnSuccessCallback = (
22
- x: number,
23
- y: number,
24
- width: number,
25
- height: number,
26
- pageX: number,
27
- pageY: number,
28
-) => void;
29
-
30
-type MeasureInWindowOnSuccessCallback = (
31
- x: number,
32
- y: number,
33
- width: number,
34
- height: number,
35
-) => void;
23
+var {
24
+ mountSafeCallback,
25
+ throwOnStylesProp,
26
+ warnForStyleProps,
27
+} = require('NativeMethodsMixinUtils');
28
37
-type MeasureLayoutOnSuccessCallback = (
38
- left: number,
39
- top: number,
40
- width: number,
41
- height: number,
42
-) => void;
43
-
44
-function warnForStyleProps(props, validAttributes) {
45
- for (var key in validAttributes.style) {
46
- if (!(validAttributes[key] || props[key] === undefined)) {
47
- console.error(
48
- 'You are setting the style `{ ' +
49
- key +
50
- ': ... }` as a prop. You ' +
51
- 'should nest it in a style object. ' +
52
- 'E.g. `{ style: { ' +
53
- key +
54
- ': ... } }`',
55
- );
56
- }
57
- }
58
-}
29
+import type {
30
+ MeasureInWindowOnSuccessCallback,
31
+ MeasureLayoutOnSuccessCallback,
32
+ MeasureOnSuccessCallback,
33
+} from 'NativeMethodsMixinUtils';
34
+import type {
35
+ ReactNativeBaseComponentViewConfig,
36
+} from 'ReactNativeViewConfigRegistry';
37
38
/**
39
* `NativeMethodsMixin` provides methods to access the underlying native
@@ -69,6 +47,10 @@ function warnForStyleProps(props, validAttributes) {
47
* information, see [Direct
48
* Manipulation](docs/direct-manipulation.html).
49
*/
50
+// TODO (bvaughn) Figure out how to use the NativeMethodsInterface type to-
51
+// ensure that these mixins and ReactNativeFiberHostComponent stay in sync.
52
+// Unfortunately, using it causes Flow to complain WRT createClass mixins:
53
+// "call of method `createClass`. Expected an exact object instead of ..."
54
var NativeMethodsMixin = {
55
/**
56
* Determines the location on screen, width, and height of the given view and
@@ -144,20 +126,15 @@ var NativeMethodsMixin = {
126
* Manipulation](docs/direct-manipulation.html)).
127
*/
128
setNativeProps: function(nativeProps: Object) {
147
- if (__DEV__) {
148
- warnForStyleProps(nativeProps, this.viewConfig.validAttributes);
149
- }
150
-
151
- var updatePayload = ReactNativeAttributePayload.create(
152
- nativeProps,
153
- this.viewConfig.validAttributes,
154
- );
129
+ // Ensure ReactNative factory function has configured findNodeHandle.
130
+ // Requiring it won't execute the factory function until first referenced.
131
+ // It's possible for tests that use ReactTestRenderer to reach this point,
132
+ // Without having executed ReactNative.
133
+ // Defer the factory function until now to avoid a cycle with UIManager.
134
+ // TODO (bvaughn) Remove this once ReactNativeStack is dropped.
135
+ require('ReactNative');
136
156
- UIManager.updateView(
157
- (ReactNative.findNodeHandle(this): any),
158
- this.viewConfig.uiViewClassName,
159
- updatePayload,
160
- );
137
+ injectedSetNativeProps(this, nativeProps);
138
},
139
140
/**
@@ -176,23 +153,113 @@ var NativeMethodsMixin = {
153
},
154
};
155
179
-function throwOnStylesProp(component, props) {
180
- if (props.styles !== undefined) {
181
- var owner = component._owner || null;
182
- var name = component.constructor.displayName;
183
- var msg = '`styles` is not a supported property of `' +
184
- name +
185
- '`, did ' +
186
- 'you mean `style` (singular)?';
187
- if (owner && owner.constructor && owner.constructor.displayName) {
188
- msg += '\n\nCheck the `' +
189
- owner.constructor.displayName +
190
- '` parent ' +
191
- ' component.';
156
+// TODO (bvaughn) Inline this once ReactNativeStack is dropped.
157
+function setNativePropsFiber(componentOrHandle: any, nativeProps: Object) {
158
+ // Class components don't have viewConfig -> validateAttributes.
159
+ // Nor does it make sense to set native props on a non-native component.
160
+ // Instead, find the nearest host component and set props on it.
161
+ // Use findNodeHandle() rather than ReactNative.findNodeHandle() because
162
+ // We want the instance/wrapper (not the native tag).
163
+ let maybeInstance;
164
+
165
+ // Fiber errors if findNodeHandle is called for an umounted component.
166
+ // Tests using ReactTestRenderer will trigger this case indirectly.
167
+ // Mimicking stack behavior, we should silently ignore this case.
168
+ // TODO Fix ReactTestRenderer so we can remove this try/catch.
169
+ try {
170
+ maybeInstance = findNodeHandle(componentOrHandle);
171
+ } catch (error) {}
172
+
173
+ // If there is no host component beneath this we should fail silently.
174
+ // This is not an error; it could mean a class component rendered null.
175
+ if (maybeInstance == null) {
176
+ return;
177
+ }
178
+
179
+ const viewConfig: ReactNativeBaseComponentViewConfig = maybeInstance.viewConfig;
180
+
181
+ if (__DEV__) {
182
+ warnForStyleProps(nativeProps, viewConfig.validAttributes);
183
+ }
184
+
185
+ var updatePayload = ReactNativeAttributePayload.create(
186
+ nativeProps,
187
+ viewConfig.validAttributes,
188
+ );
189
+
190
+ UIManager.updateView(
191
+ maybeInstance._nativeTag,
192
+ viewConfig.uiViewClassName,
193
+ updatePayload,
194
+ );
195
+}
196
+
197
+// TODO (bvaughn) Remove this once ReactNativeStack is dropped.
198
+function setNativePropsStack(componentOrHandle: any, nativeProps: Object) {
199
+ // Class components don't have viewConfig -> validateAttributes.
200
+ // Nor does it make sense to set native props on a non-native component.
201
+ // Instead, find the nearest host component and set props on it.
202
+ // Use findNodeHandle() rather than ReactNative.findNodeHandle() because
203
+ // We want the instance/wrapper (not the native tag).
204
+ let maybeInstance = findNodeHandle(componentOrHandle);
205
+
206
+ // If there is no host component beneath this we should fail silently.
207
+ // This is not an error; it could mean a class component rendered null.
208
+ if (maybeInstance == null) {
209
+ return;
210
+ }
211
+
212
+ let viewConfig: ReactNativeBaseComponentViewConfig;
213
+ if (maybeInstance.viewConfig !== undefined) {
214
+ // ReactNativeBaseComponent
215
+ viewConfig = maybeInstance.viewConfig;
216
+ } else if (
217
+ maybeInstance._instance !== undefined &&
218
+ maybeInstance._instance.viewConfig !== undefined
219
+ ) {
220
+ // ReactCompositeComponentWrapper
221
+ // Some instances (eg Text) define their own viewConfig
222
+ viewConfig = maybeInstance._instance.viewConfig;
223
+ } else {
224
+ // ReactCompositeComponentWrapper
225
+ // Other instances (eg TextInput) defer to their children's viewConfig
226
+ while (maybeInstance._renderedComponent !== undefined) {
227
+ maybeInstance = maybeInstance._renderedComponent;
228
}
193
- throw new Error(msg);
229
+ viewConfig = maybeInstance.viewConfig;
230
}
231
+
232
+ const tag: number = typeof maybeInstance.getHostNode === 'function'
233
+ ? maybeInstance.getHostNode()
234
+ : maybeInstance._rootNodeID;
235
+
236
+ if (__DEV__) {
237
+ warnForStyleProps(nativeProps, viewConfig.validAttributes);
238
+ }
239
+
240
+ var updatePayload = ReactNativeAttributePayload.create(
241
+ nativeProps,
242
+ viewConfig.validAttributes,
243
+ );
244
+
245
+ UIManager.updateView(tag, viewConfig.uiViewClassName, updatePayload);
246
+}
247
+
248
+// Switching based on fiber vs stack to avoid a lot of inline checks at runtime.
249
+// HACK Normally this injection would be done by the renderer, but in this case
250
+// that would result in a cycle between ReactNative and NativeMethodsMixin.
251
+// We avoid requiring additional code for this injection so it's probably ok?
252
+// TODO (bvaughn) Remove this once ReactNativeStack is gone.
253
+let injectedSetNativeProps: (
254
+ componentOrHandle: any,
255
+ nativeProps: Object,
256
+) => void;
257
+if (ReactNativeFeatureFlags.useFiber) {
258
+ injectedSetNativeProps = setNativePropsFiber;
259
+} else {
260
+ injectedSetNativeProps = setNativePropsStack;
261
}
262
+
263
if (__DEV__) {
264
// hide this from Flow since we can't define these properties outside of
265
// __DEV__ without actually implementing them (setting them to undefined
@@ -211,23 +278,4 @@ if (__DEV__) {
278
};
279
}
280
214
-/**
215
- * In the future, we should cleanup callbacks by cancelling them instead of
216
- * using this.
217
- */
218
-function mountSafeCallback(
219
- context: ReactComponent<any, any, any>,
220
- callback: ?Function,
221
-): any {
222
- return function() {
223
- if (
224
- !callback ||
225
- (typeof context.isMounted === 'function' && !context.isMounted())
226
- ) {
227
- return undefined;
228
- }
229
- return callback.apply(context, arguments);
230
- };
231
-}
232
-
281
module.exports = NativeMethodsMixin;
src/renderers/native/NativeMethodsMixinUtils.js
new
+108
@@ -0,0 +1,108 @@
1
+/**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ *
9
+ * @providesModule NativeMethodsMixinUtils
10
+ * @flow
11
+ */
12
+'use strict';
13
+
14
+export type MeasureOnSuccessCallback = (
15
+ x: number,
16
+ y: number,
17
+ width: number,
18
+ height: number,
19
+ pageX: number,
20
+ pageY: number,
21
+) => void;
22
+
23
+export type MeasureInWindowOnSuccessCallback = (
24
+ x: number,
25
+ y: number,
26
+ width: number,
27
+ height: number,
28
+) => void;
29
+
30
+export type MeasureLayoutOnSuccessCallback = (
31
+ left: number,
32
+ top: number,
33
+ width: number,
34
+ height: number,
35
+) => void;
36
+
37
+/**
38
+ * Shared between ReactNativeFiberHostComponent and NativeMethodsMixin to keep
39
+ * API in sync.
40
+ */
41
+export interface NativeMethodsInterface {
42
+ blur(): void,
43
+ focus(): void,
44
+ measure(callback: MeasureOnSuccessCallback): void,
45
+ measureInWindow(callback: MeasureInWindowOnSuccessCallback): void,
46
+ measureLayout(
47
+ relativeToNativeNode: number,
48
+ onSuccess: MeasureLayoutOnSuccessCallback,
49
+ onFail: () => void,
50
+ ): void,
51
+ setNativeProps(nativeProps: Object): void,
52
+}
53
+
54
+/**
55
+ * In the future, we should cleanup callbacks by cancelling them instead of
56
+ * using this.
57
+ */
58
+function mountSafeCallback(context: any, callback: ?Function): any {
59
+ return function() {
60
+ if (
61
+ !callback ||
62
+ (typeof context.isMounted === 'function' && !context.isMounted())
63
+ ) {
64
+ return undefined;
65
+ }
66
+ return callback.apply(context, arguments);
67
+ };
68
+}
69
+
70
+function throwOnStylesProp(component: any, props: any) {
71
+ if (props.styles !== undefined) {
72
+ var owner = component._owner || null;
73
+ var name = component.constructor.displayName;
74
+ var msg = '`styles` is not a supported property of `' +
75
+ name +
76
+ '`, did ' +
77
+ 'you mean `style` (singular)?';
78
+ if (owner && owner.constructor && owner.constructor.displayName) {
79
+ msg += '\n\nCheck the `' +
80
+ owner.constructor.displayName +
81
+ '` parent ' +
82
+ ' component.';
83
+ }
84
+ throw new Error(msg);
85
+ }
86
+}
87
+
88
+function warnForStyleProps(props: any, validAttributes: any) {
89
+ for (var key in validAttributes.style) {
90
+ if (!(validAttributes[key] || props[key] === undefined)) {
91
+ console.error(
92
+ 'You are setting the style `{ ' +
93
+ key +
94
+ ': ... }` as a prop. You ' +
95
+ 'should nest it in a style object. ' +
96
+ 'E.g. `{ style: { ' +
97
+ key +
98
+ ': ... } }`',
99
+ );
100
+ }
101
+ }
102
+}
103
+
104
+module.exports = {
105
+ mountSafeCallback,
106
+ throwOnStylesProp,
107
+ warnForStyleProps,
108
+};
src/renderers/native/ReactNative.js
+5
-2
@@ -11,5 +11,8 @@
11
*/
12
'use strict';
13
14
-// TODO (bvaughn) Enable Fiber experiement via ReactNativeFeatureFlags
15
-module.exports = require('ReactNativeStack');
14
+const ReactNativeFeatureFlags = require('ReactNativeFeatureFlags');
15
+
16
+module.exports = ReactNativeFeatureFlags.useFiber
17
+ ? require('ReactNativeFiber')
18
+ : require('ReactNativeStack');
src/renderers/native/ReactNativeFiber.js
+24
-25
@@ -12,18 +12,11 @@
12
13
'use strict';
14
15
-import type {Element} from 'React';
16
-import type {Fiber} from 'ReactFiber';
17
-import type {ReactNodeList} from 'ReactTypes';
18
-import type {
19
- ReactNativeBaseComponentViewConfig,
20
-} from 'ReactNativeViewConfigRegistry';
21
-
22
-const NativeMethodsMixin = require('NativeMethodsMixin');
15
const ReactFiberReconciler = require('ReactFiberReconciler');
16
const ReactGenericBatching = require('ReactGenericBatching');
17
const ReactNativeAttributePayload = require('ReactNativeAttributePayload');
18
const ReactNativeComponentTree = require('ReactNativeComponentTree');
19
+const ReactNativeFiberHostComponent = require('ReactNativeFiberHostComponent');
20
const ReactNativeInjection = require('ReactNativeInjection');
21
const ReactNativeTagHandles = require('ReactNativeTagHandles');
22
const ReactNativeViewConfigRegistry = require('ReactNativeViewConfigRegistry');
@@ -36,6 +29,13 @@ const findNodeHandle = require('findNodeHandle');
29
const invariant = require('fbjs/lib/invariant');
30
31
const {injectInternals} = require('ReactFiberDevToolsHook');
32
+
33
+import type {Element} from 'React';
34
+import type {Fiber} from 'ReactFiber';
35
+import type {
36
+ ReactNativeBaseComponentViewConfig,
37
+} from 'ReactNativeViewConfigRegistry';
38
+import type {ReactNodeList} from 'ReactTypes';
39
const {
40
precacheFiberNode,
41
uncacheFiberNode,
@@ -45,7 +45,7 @@ const {
45
ReactNativeInjection.inject();
46
47
type Container = number;
48
-type Instance = {
48
+export type Instance = {
49
_children: Array<Instance | number>,
50
_nativeTag: number,
51
viewConfig: ReactNativeBaseComponentViewConfig,
@@ -53,13 +53,6 @@ type Instance = {
53
type Props = Object;
54
type TextInstance = number;
55
56
-function NativeHostComponent(tag, viewConfig) {
57
- this._nativeTag = tag;
58
- this._children = [];
59
- this.viewConfig = viewConfig;
60
-}
61
-Object.assign(NativeHostComponent.prototype, NativeMethodsMixin);
62
-
56
function recursivelyUncacheFiberNode(node: Instance | TextInstance) {
57
if (typeof node === 'number') {
58
// Leaf node (eg text)
@@ -162,7 +155,7 @@ const NativeRenderer = ReactFiberReconciler({
155
const viewConfig = ReactNativeViewConfigRegistry.get(type);
156
157
if (__DEV__) {
165
- for (let key in viewConfig.validAttributes) {
158
+ for (const key in viewConfig.validAttributes) {
159
if (props.hasOwnProperty(key)) {
160
deepFreezeAndThrowOnMutationInDev(props[key]);
161
}
@@ -181,12 +174,14 @@ const NativeRenderer = ReactFiberReconciler({
174
updatePayload, // props
175
);
176
184
- const component = new NativeHostComponent(tag, viewConfig);
177
+ const component = new ReactNativeFiberHostComponent(tag, viewConfig);
178
179
precacheFiberNode(internalInstanceHandle, tag);
180
updateFiberProps(tag, props);
181
189
- return component;
182
+ // Not sure how to avoid this cast. Flow is okay if the component is defined
183
+ // in the same file but if it's external it can't see the types.
184
+ return ((component: any): Instance);
185
},
186
187
createTextInstance(
@@ -377,14 +372,18 @@ ReactGenericBatching.injection.injectFiberBatchedUpdates(
372
373
const roots = new Map();
374
380
-findNodeHandle.injection.injectFindNode((fiber: Fiber) => {
381
- const instance: any = NativeRenderer.findHostInstance(fiber);
382
- return instance ? instance._nativeTag : null;
383
-});
384
-findNodeHandle.injection.injectFindRootNodeID(instance => instance._nativeTag);
375
+findNodeHandle.injection.injectFindNode((fiber: Fiber) =>
376
+ NativeRenderer.findHostInstance(fiber));
377
+findNodeHandle.injection.injectFindRootNodeID(instance => instance);
378
379
const ReactNative = {
387
- findNodeHandle,
380
+ // External users of findNodeHandle() expect the host tag number return type.
381
+ // The injected findNodeHandle() strategy returns the instance wrapper though.
382
+ // See NativeMethodsMixin#setNativeProps for more info on why this is done.
383
+ findNodeHandle(componentOrHandle: any): ?number {
384
+ const instance: any = findNodeHandle(componentOrHandle);
385
+ return instance ? instance._nativeTag : null;
386
+ },
387
388
render(element: Element<any>, containerTag: any, callback: ?Function) {
389
let root = roots.get(containerTag);
src/renderers/native/ReactNativeFiberHostComponent.js
new
+104
@@ -0,0 +1,104 @@
1
+/**
2
+ * Copyright 2013-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ *
9
+ * @providesModule ReactNativeFiberHostComponent
10
+ * @flow
11
+ * @preventMunge
12
+ */
13
+
14
+'use strict';
15
+
16
+var ReactNativeAttributePayload = require('ReactNativeAttributePayload');
17
+var TextInputState = require('TextInputState');
18
+var UIManager = require('UIManager');
19
+
20
+var {
21
+ mountSafeCallback,
22
+ warnForStyleProps,
23
+} = require('NativeMethodsMixinUtils');
24
+
25
+import type {
26
+ MeasureInWindowOnSuccessCallback,
27
+ MeasureLayoutOnSuccessCallback,
28
+ MeasureOnSuccessCallback,
29
+ NativeMethodsInterface,
30
+} from 'NativeMethodsMixinUtils';
31
+import type {Instance} from 'ReactNativeFiber';
32
+import type {
33
+ ReactNativeBaseComponentViewConfig,
34
+} from 'ReactNativeViewConfigRegistry';
35
+
36
+/**
37
+ * This component defines the same methods as NativeMethodsMixin but without the
38
+ * findNodeHandle wrapper. This wrapper is unnecessary for HostComponent views
39
+ * and would also result in a circular require.js dependency (since
40
+ * ReactNativeFiber depends on this component and NativeMethodsMixin depends on
41
+ * ReactNativeFiber).
42
+ */
43
+class ReactNativeFiberHostComponent implements NativeMethodsInterface {
44
+ _children: Array<Instance | number>;
45
+ _nativeTag: number;
46
+ viewConfig: ReactNativeBaseComponentViewConfig;
47
+
48
+ constructor(tag: number, viewConfig: ReactNativeBaseComponentViewConfig) {
49
+ this._nativeTag = tag;
50
+ this._children = [];
51
+ this.viewConfig = viewConfig;
52
+ }
53
+
54
+ blur() {
55
+ TextInputState.blurTextInput(this._nativeTag);
56
+ }
57
+
58
+ focus() {
59
+ TextInputState.focusTextInput(this._nativeTag);
60
+ }
61
+
62
+ measure(callback: MeasureOnSuccessCallback) {
63
+ UIManager.measure(this._nativeTag, mountSafeCallback(this, callback));
64
+ }
65
+
66
+ measureInWindow(callback: MeasureInWindowOnSuccessCallback) {
67
+ UIManager.measureInWindow(
68
+ this._nativeTag,
69
+ mountSafeCallback(this, callback),
70
+ );
71
+ }
72
+
73
+ measureLayout(
74
+ relativeToNativeNode: number,
75
+ onSuccess: MeasureLayoutOnSuccessCallback,
76
+ onFail: () => void /* currently unused */,
77
+ ) {
78
+ UIManager.measureLayout(
79
+ this._nativeTag,
80
+ relativeToNativeNode,
81
+ mountSafeCallback(this, onFail),
82
+ mountSafeCallback(this, onSuccess),
83
+ );
84
+ }
85
+
86
+ setNativeProps(nativeProps: Object) {
87
+ if (__DEV__) {
88
+ warnForStyleProps(nativeProps, this.viewConfig.validAttributes);
89
+ }
90
+
91
+ var updatePayload = ReactNativeAttributePayload.create(
92
+ nativeProps,
93
+ this.viewConfig.validAttributes,
94
+ );
95
+
96
+ UIManager.updateView(
97
+ this._nativeTag,
98
+ this.viewConfig.uiViewClassName,
99
+ updatePayload,
100
+ );
101
+ }
102
+}
103
+
104
+module.exports = ReactNativeFiberHostComponent;
src/renderers/native/ReactNativeStack.js
+9
-5
@@ -13,8 +13,8 @@
13
14
var ReactNativeComponentTree = require('ReactNativeComponentTree');
15
var ReactNativeInjection = require('ReactNativeInjection');
16
-var ReactNativeStackInjection = require('ReactNativeStackInjection');
16
var ReactNativeMount = require('ReactNativeMount');
17
+var ReactNativeStackInjection = require('ReactNativeStackInjection');
18
var ReactUpdates = require('ReactUpdates');
19
20
var findNodeHandle = require('findNodeHandle');
@@ -30,12 +30,16 @@ var render = function(
30
return ReactNativeMount.renderComponent(element, mountInto, callback);
31
};
32
33
-findNodeHandle.injection.injectFindNode(instance => instance.getHostNode());
34
-findNodeHandle.injection.injectFindRootNodeID(instance => instance._rootNodeID);
35
-
33
var ReactNative = {
34
hasReactNativeInitialized: false,
38
- findNodeHandle: findNodeHandle,
35
+
36
+ // External users of findNodeHandle() expect the host tag number return type.
37
+ // The injected findNodeHandle() strategy returns the instance wrapper though.
38
+ // See NativeMethodsMixin#setNativeProps for more info on why this is done.
39
+ findNodeHandle(componentOrHandle: any): ?number {
40
+ return findNodeHandle(componentOrHandle).getHostNode();
41
+ },
42
+
43
render: render,
44
unmountComponentAtNode: ReactNativeMount.unmountComponentAtNode,
45
src/renderers/native/ReactNativeStackInjection.js
+2
-4
@@ -60,10 +60,8 @@ function inject() {
60
);
61
};
62
63
- findNodeHandle.injection.injectFindNode(instance => instance.getHostNode());
64
- findNodeHandle.injection.injectFindRootNodeID(
65
- instance => instance._rootNodeID,
66
- );
63
+ findNodeHandle.injection.injectFindNode(instance => instance);
64
+ findNodeHandle.injection.injectFindRootNodeID(instance => instance);
65
66
ReactEmptyComponent.injection.injectEmptyComponentFactory(EmptyComponent);
67
src/renderers/native/createReactNativeComponentClass.js
+1
-1
@@ -13,8 +13,8 @@
13
'use strict';
14
15
const ReactNativeBaseComponent = require('ReactNativeBaseComponent');
16
-const ReactNativeViewConfigRegistry = require('ReactNativeViewConfigRegistry');
16
const ReactNativeFeatureFlags = require('ReactNativeFeatureFlags');
17
+const ReactNativeViewConfigRegistry = require('ReactNativeViewConfigRegistry');
18
19
// See also ReactNativeBaseComponent
20
type ReactNativeBaseComponentViewConfig = {
src/renderers/native/findNodeHandle.js
+4
-1
@@ -53,7 +53,10 @@ import type {ReactInstance} from 'ReactInstanceType';
53
let injectedFindNode;
54
let injectedFindRootNodeID;
55
56
-function findNodeHandle(componentOrHandle: any): ?number {
56
+// TODO (bvaughn) Rename the findNodeHandle module to something more descriptive
57
+// eg findInternalHostInstance. This will reduce the likelihood of someone
58
+// accidentally deep-requiring this version.
59
+function findNodeHandle(componentOrHandle: any): any {
60
if (__DEV__) {
61
// TODO: fix this unsafe cast to work with Fiber.
62
var owner = ((ReactCurrentOwner.current: any): ReactInstance | null);