@samitouri / QOS-React / commits / 7f665da0ee

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);