From 2d6be757df86177ca8590bf7c361d6c910640895 Mon Sep 17 00:00:00 2001 From: Eli White Date: Thu, 13 Feb 2020 15:09:25 -0800 Subject: [PATCH] [Native] Delete NativeComponent and NativeMethodsMixin (#18036) * [Native] Delete NativeComponent and NativeMethodsMixin * Remove more files --- .../src/NativeMethodsMixin.js | 330 --------------- .../react-native-renderer/src/ReactFabric.js | 9 +- .../src/ReactNativeComponent.js | 285 ------------- .../src/ReactNativeFiberHostComponent.js | 7 - .../src/ReactNativeRenderer.js | 6 - .../src/ReactNativeTypes.js | 36 +- .../__tests__/ReactFabric-test.internal.js | 369 ++++++----------- .../ReactNativeMount-test.internal.js | 380 +++++++----------- ...eateReactClassIntegration-test.internal.js | 74 ---- .../shims/react-native/NativeMethodsMixin.js | 21 - 10 files changed, 260 insertions(+), 1257 deletions(-) delete mode 100644 packages/react-native-renderer/src/NativeMethodsMixin.js delete mode 100644 packages/react-native-renderer/src/ReactNativeComponent.js delete mode 100644 packages/react/src/__tests__/createReactClassIntegration-test.internal.js delete mode 100644 scripts/rollup/shims/react-native/NativeMethodsMixin.js diff --git a/packages/react-native-renderer/src/NativeMethodsMixin.js b/packages/react-native-renderer/src/NativeMethodsMixin.js deleted file mode 100644 index 4c15f4925865e..0000000000000 --- a/packages/react-native-renderer/src/NativeMethodsMixin.js +++ /dev/null @@ -1,330 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -import type { - MeasureInWindowOnSuccessCallback, - MeasureLayoutOnSuccessCallback, - MeasureOnSuccessCallback, - NativeMethodsMixinType, - ReactNativeBaseComponentViewConfig, -} from './ReactNativeTypes'; - -import invariant from 'shared/invariant'; -// Modules provided by RN: -import { - TextInputState, - UIManager, -} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; - -import {create} from './ReactNativeAttributePayload'; -import { - mountSafeCallback_NOT_REALLY_SAFE, - throwOnStylesProp, - warnForStyleProps, -} from './NativeMethodsMixinUtils'; - -export default function( - findNodeHandle: any => ?number, - findHostInstance: any => any, -) { - /** - * `NativeMethodsMixin` provides methods to access the underlying native - * component directly. This can be useful in cases when you want to focus - * a view or measure its on-screen dimensions, for example. - * - * The methods described here are available on most of the default components - * provided by React Native. Note, however, that they are *not* available on - * composite components that aren't directly backed by a native view. This will - * generally include most components that you define in your own app. For more - * information, see [Direct - * Manipulation](docs/direct-manipulation.html). - * - * Note the Flow $Exact<> syntax is required to support mixins. - * React createClass mixins can only be used with exact types. - */ - const NativeMethodsMixin: $Exact = { - /** - * Determines the location on screen, width, and height of the given view and - * returns the values via an async callback. If successful, the callback will - * be called with the following arguments: - * - * - x - * - y - * - width - * - height - * - pageX - * - pageY - * - * Note that these measurements are not available until after the rendering - * has been completed in native. If you need the measurements as soon as - * possible, consider using the [`onLayout` - * prop](docs/view.html#onlayout) instead. - */ - measure: function(callback: MeasureOnSuccessCallback) { - let maybeInstance; - - // Fiber errors if findNodeHandle is called for an umounted component. - // Tests using ReactTestRenderer will trigger this case indirectly. - // Mimicking stack behavior, we should silently ignore this case. - // TODO Fix ReactTestRenderer so we can remove this try/catch. - try { - maybeInstance = findHostInstance(this); - } catch (error) {} - - // If there is no host component beneath this we should fail silently. - // This is not an error; it could mean a class component rendered null. - if (maybeInstance == null) { - return; - } - - if (maybeInstance.canonical) { - // We can't call FabricUIManager here because it won't be loaded in paper - // at initialization time. See https://github.com/facebook/react/pull/15490 - // for more info. - nativeFabricUIManager.measure( - maybeInstance.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback), - ); - } else { - UIManager.measure( - findNodeHandle(this), - mountSafeCallback_NOT_REALLY_SAFE(this, callback), - ); - } - }, - - /** - * Determines the location of the given view in the window and returns the - * values via an async callback. If the React root view is embedded in - * another native view, this will give you the absolute coordinates. If - * successful, the callback will be called with the following - * arguments: - * - * - x - * - y - * - width - * - height - * - * Note that these measurements are not available until after the rendering - * has been completed in native. - */ - measureInWindow: function(callback: MeasureInWindowOnSuccessCallback) { - let maybeInstance; - - // Fiber errors if findNodeHandle is called for an umounted component. - // Tests using ReactTestRenderer will trigger this case indirectly. - // Mimicking stack behavior, we should silently ignore this case. - // TODO Fix ReactTestRenderer so we can remove this try/catch. - try { - maybeInstance = findHostInstance(this); - } catch (error) {} - - // If there is no host component beneath this we should fail silently. - // This is not an error; it could mean a class component rendered null. - if (maybeInstance == null) { - return; - } - - if (maybeInstance.canonical) { - // We can't call FabricUIManager here because it won't be loaded in paper - // at initialization time. See https://github.com/facebook/react/pull/15490 - // for more info. - nativeFabricUIManager.measureInWindow( - maybeInstance.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback), - ); - } else { - UIManager.measureInWindow( - findNodeHandle(this), - mountSafeCallback_NOT_REALLY_SAFE(this, callback), - ); - } - }, - - /** - * Like [`measure()`](#measure), but measures the view relative an ancestor, - * specified as `relativeToNativeNode`. This means that the returned x, y - * are relative to the origin x, y of the ancestor view. - * - * As always, to obtain a native node handle for a component, you can use - * `findNodeHandle(component)`. - */ - measureLayout: function( - relativeToNativeNode: number | Object, - onSuccess: MeasureLayoutOnSuccessCallback, - onFail?: () => void /* currently unused */, - ) { - let maybeInstance; - - // Fiber errors if findNodeHandle is called for an umounted component. - // Tests using ReactTestRenderer will trigger this case indirectly. - // Mimicking stack behavior, we should silently ignore this case. - // TODO Fix ReactTestRenderer so we can remove this try/catch. - try { - maybeInstance = findHostInstance(this); - } catch (error) {} - - // If there is no host component beneath this we should fail silently. - // This is not an error; it could mean a class component rendered null. - if (maybeInstance == null) { - return; - } - - if (maybeInstance.canonical) { - if (__DEV__) { - console.error( - 'Warning: measureLayout on components using NativeMethodsMixin ' + - 'or ReactNative.NativeComponent is not currently supported in Fabric. ' + - 'measureLayout must be called on a native ref. Consider using forwardRef.', - ); - } - return; - } else { - let relativeNode; - - if (typeof relativeToNativeNode === 'number') { - // Already a node handle - relativeNode = relativeToNativeNode; - } else if (relativeToNativeNode._nativeTag) { - relativeNode = relativeToNativeNode._nativeTag; - } - - if (relativeNode == null) { - if (__DEV__) { - console.error( - 'Warning: ref.measureLayout must be called with a node handle or a ref to a native component.', - ); - } - - return; - } - - UIManager.measureLayout( - findNodeHandle(this), - relativeNode, - mountSafeCallback_NOT_REALLY_SAFE(this, onFail), - mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess), - ); - } - }, - - /** - * This function sends props straight to native. They will not participate in - * future diff process - this means that if you do not include them in the - * next render, they will remain active (see [Direct - * Manipulation](docs/direct-manipulation.html)). - */ - setNativeProps: function(nativeProps: Object) { - // Class components don't have viewConfig -> validateAttributes. - // Nor does it make sense to set native props on a non-native component. - // Instead, find the nearest host component and set props on it. - // Use findNodeHandle() rather than findNodeHandle() because - // We want the instance/wrapper (not the native tag). - let maybeInstance; - - // Fiber errors if findNodeHandle is called for an umounted component. - // Tests using ReactTestRenderer will trigger this case indirectly. - // Mimicking stack behavior, we should silently ignore this case. - // TODO Fix ReactTestRenderer so we can remove this try/catch. - try { - maybeInstance = findHostInstance(this); - } catch (error) {} - - // If there is no host component beneath this we should fail silently. - // This is not an error; it could mean a class component rendered null. - if (maybeInstance == null) { - return; - } - - if (maybeInstance.canonical) { - if (__DEV__) { - console.error( - 'Warning: setNativeProps is not currently supported in Fabric', - ); - } - return; - } - - const nativeTag = - maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; - const viewConfig: ReactNativeBaseComponentViewConfig<> = - maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; - - if (__DEV__) { - warnForStyleProps(nativeProps, viewConfig.validAttributes); - } - - const updatePayload = create(nativeProps, viewConfig.validAttributes); - - // Avoid the overhead of bridge calls if there's no update. - // This is an expensive no-op for Android, and causes an unnecessary - // view invalidation for certain components (eg RCTTextInput) on iOS. - if (updatePayload != null) { - UIManager.updateView( - nativeTag, - viewConfig.uiViewClassName, - updatePayload, - ); - } - }, - - /** - * Requests focus for the given input or view. The exact behavior triggered - * will depend on the platform and type of view. - */ - focus: function() { - TextInputState.focusTextInput(findNodeHandle(this)); - }, - - /** - * Removes focus from an input or view. This is the opposite of `focus()`. - */ - blur: function() { - TextInputState.blurTextInput(findNodeHandle(this)); - }, - }; - - if (__DEV__) { - // hide this from Flow since we can't define these properties outside of - // __DEV__ without actually implementing them (setting them to undefined - // isn't allowed by ReactClass) - const NativeMethodsMixin_DEV = (NativeMethodsMixin: any); - invariant( - !NativeMethodsMixin_DEV.componentWillMount && - !NativeMethodsMixin_DEV.componentWillReceiveProps && - !NativeMethodsMixin_DEV.UNSAFE_componentWillMount && - !NativeMethodsMixin_DEV.UNSAFE_componentWillReceiveProps, - 'Do not override existing functions.', - ); - // TODO (bvaughn) Remove cWM and cWRP in a future version of React Native, - // Once these lifecycles have been remove from the reconciler. - NativeMethodsMixin_DEV.componentWillMount = function() { - throwOnStylesProp(this, this.props); - }; - NativeMethodsMixin_DEV.componentWillReceiveProps = function(newProps) { - throwOnStylesProp(this, newProps); - }; - NativeMethodsMixin_DEV.UNSAFE_componentWillMount = function() { - throwOnStylesProp(this, this.props); - }; - NativeMethodsMixin_DEV.UNSAFE_componentWillReceiveProps = function( - newProps, - ) { - throwOnStylesProp(this, newProps); - }; - - // React may warn about cWM/cWRP/cWU methods being deprecated. - // Add a flag to suppress these warnings for this special case. - // TODO (bvaughn) Remove this flag once the above methods have been removed. - NativeMethodsMixin_DEV.componentWillMount.__suppressDeprecationWarning = true; - NativeMethodsMixin_DEV.componentWillReceiveProps.__suppressDeprecationWarning = true; - } - - return NativeMethodsMixin; -} diff --git a/packages/react-native-renderer/src/ReactFabric.js b/packages/react-native-renderer/src/ReactFabric.js index d9b532e497984..13ae10b1f6276 100644 --- a/packages/react-native-renderer/src/ReactFabric.js +++ b/packages/react-native-renderer/src/ReactFabric.js @@ -32,8 +32,6 @@ import ReactVersion from 'shared/ReactVersion'; // Module provided by RN: import {UIManager} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; -import NativeMethodsMixin from './NativeMethodsMixin'; -import ReactNativeComponent from './ReactNativeComponent'; import {getClosestInstanceFromNode} from './ReactFabricComponentTree'; import {getInspectorDataForViewTag} from './ReactNativeFiberInspector'; @@ -155,8 +153,6 @@ setBatchingImplementation( const roots = new Map(); const ReactFabric: ReactFabricType = { - NativeComponent: ReactNativeComponent(findNodeHandle, findHostInstance), - // This is needed for implementation details of TouchableNativeFeedback // Remove this once TouchableNativeFeedback doesn't use cloneElement findHostInstance_DEPRECATED, @@ -223,10 +219,7 @@ const ReactFabric: ReactFabricType = { return createPortal(children, containerTag, null, key); }, - __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: { - // Used as a mixin in many createClass-based components - NativeMethodsMixin: NativeMethodsMixin(findNodeHandle, findHostInstance), - }, + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {}, }; injectIntoDevTools({ diff --git a/packages/react-native-renderer/src/ReactNativeComponent.js b/packages/react-native-renderer/src/ReactNativeComponent.js deleted file mode 100644 index fe0425e04e333..0000000000000 --- a/packages/react-native-renderer/src/ReactNativeComponent.js +++ /dev/null @@ -1,285 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - * @format - */ - -import type { - MeasureInWindowOnSuccessCallback, - MeasureLayoutOnSuccessCallback, - MeasureOnSuccessCallback, - NativeMethods, - ReactNativeBaseComponentViewConfig, -} from './ReactNativeTypes'; - -import React from 'react'; -// Modules provided by RN: -import { - TextInputState, - UIManager, -} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; - -import {create} from './ReactNativeAttributePayload'; -import {mountSafeCallback_NOT_REALLY_SAFE} from './NativeMethodsMixinUtils'; - -export default function( - findNodeHandle: any => ?number, - findHostInstance: any => any, -) { - /** - * Superclass that provides methods to access the underlying native component. - * This can be useful when you want to focus a view or measure its dimensions. - * - * Methods implemented by this class are available on most default components - * provided by React Native. However, they are *not* available on composite - * components that are not directly backed by a native view. For more - * information, see [Direct Manipulation](docs/direct-manipulation.html). - * - * @abstract - */ - class ReactNativeComponent extends React.Component { - /** - * Due to bugs in Flow's handling of React.createClass, some fields already - * declared in the base class need to be redeclared below. - */ - props: Props; - - /** - * Removes focus. This is the opposite of `focus()`. - */ - blur(): void { - TextInputState.blurTextInput(findNodeHandle(this)); - } - - /** - * Requests focus. The exact behavior depends on the platform and view. - */ - focus(): void { - TextInputState.focusTextInput(findNodeHandle(this)); - } - - /** - * Measures the on-screen location and dimensions. If successful, the callback - * will be called asynchronously with the following arguments: - * - * - x - * - y - * - width - * - height - * - pageX - * - pageY - * - * These values are not available until after natives rendering completes. If - * you need the measurements as soon as possible, consider using the - * [`onLayout` prop](docs/view.html#onlayout) instead. - */ - measure(callback: MeasureOnSuccessCallback): void { - let maybeInstance; - - // Fiber errors if findNodeHandle is called for an umounted component. - // Tests using ReactTestRenderer will trigger this case indirectly. - // Mimicking stack behavior, we should silently ignore this case. - // TODO Fix ReactTestRenderer so we can remove this try/catch. - try { - maybeInstance = findHostInstance(this); - } catch (error) {} - - // If there is no host component beneath this we should fail silently. - // This is not an error; it could mean a class component rendered null. - if (maybeInstance == null) { - return; - } - - if (maybeInstance.canonical) { - // We can't call FabricUIManager here because it won't be loaded in paper - // at initialization time. See https://github.com/facebook/react/pull/15490 - // for more info. - nativeFabricUIManager.measure( - maybeInstance.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback), - ); - } else { - UIManager.measure( - findNodeHandle(this), - mountSafeCallback_NOT_REALLY_SAFE(this, callback), - ); - } - } - - /** - * Measures the on-screen location and dimensions. Even if the React Native - * root view is embedded within another native view, this method will give you - * the absolute coordinates measured from the window. If successful, the - * callback will be called asynchronously with the following arguments: - * - * - x - * - y - * - width - * - height - * - * These values are not available until after natives rendering completes. - */ - measureInWindow(callback: MeasureInWindowOnSuccessCallback): void { - let maybeInstance; - - // Fiber errors if findNodeHandle is called for an umounted component. - // Tests using ReactTestRenderer will trigger this case indirectly. - // Mimicking stack behavior, we should silently ignore this case. - // TODO Fix ReactTestRenderer so we can remove this try/catch. - try { - maybeInstance = findHostInstance(this); - } catch (error) {} - - // If there is no host component beneath this we should fail silently. - // This is not an error; it could mean a class component rendered null. - if (maybeInstance == null) { - return; - } - - if (maybeInstance.canonical) { - // We can't call FabricUIManager here because it won't be loaded in paper - // at initialization time. See https://github.com/facebook/react/pull/15490 - // for more info. - nativeFabricUIManager.measureInWindow( - maybeInstance.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback), - ); - } else { - UIManager.measureInWindow( - findNodeHandle(this), - mountSafeCallback_NOT_REALLY_SAFE(this, callback), - ); - } - } - - /** - * Similar to [`measure()`](#measure), but the resulting location will be - * relative to the supplied ancestor's location. - * - * Obtain a native node handle with `ReactNative.findNodeHandle(component)`. - */ - measureLayout( - relativeToNativeNode: number | Object, - onSuccess: MeasureLayoutOnSuccessCallback, - onFail?: () => void /* currently unused */, - ): void { - let maybeInstance; - - // Fiber errors if findNodeHandle is called for an umounted component. - // Tests using ReactTestRenderer will trigger this case indirectly. - // Mimicking stack behavior, we should silently ignore this case. - // TODO Fix ReactTestRenderer so we can remove this try/catch. - try { - maybeInstance = findHostInstance(this); - } catch (error) {} - - // If there is no host component beneath this we should fail silently. - // This is not an error; it could mean a class component rendered null. - if (maybeInstance == null) { - return; - } - - if (maybeInstance.canonical) { - if (__DEV__) { - console.error( - 'Warning: measureLayout on components using NativeMethodsMixin ' + - 'or ReactNative.NativeComponent is not currently supported in Fabric. ' + - 'measureLayout must be called on a native ref. Consider using forwardRef.', - ); - } - return; - } else { - let relativeNode; - - if (typeof relativeToNativeNode === 'number') { - // Already a node handle - relativeNode = relativeToNativeNode; - } else if (relativeToNativeNode._nativeTag) { - relativeNode = relativeToNativeNode._nativeTag; - } - - if (relativeNode == null) { - if (__DEV__) { - console.error( - 'Warning: ref.measureLayout must be called with a node handle or a ref to a native component.', - ); - } - - return; - } - - UIManager.measureLayout( - findNodeHandle(this), - relativeNode, - mountSafeCallback_NOT_REALLY_SAFE(this, onFail), - mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess), - ); - } - } - - /** - * This function sends props straight to native. They will not participate in - * future diff process - this means that if you do not include them in the - * next render, they will remain active (see [Direct - * Manipulation](docs/direct-manipulation.html)). - */ - setNativeProps(nativeProps: Object): void { - // Class components don't have viewConfig -> validateAttributes. - // Nor does it make sense to set native props on a non-native component. - // Instead, find the nearest host component and set props on it. - // Use findNodeHandle() rather than ReactNative.findNodeHandle() because - // We want the instance/wrapper (not the native tag). - let maybeInstance; - - // Fiber errors if findNodeHandle is called for an umounted component. - // Tests using ReactTestRenderer will trigger this case indirectly. - // Mimicking stack behavior, we should silently ignore this case. - // TODO Fix ReactTestRenderer so we can remove this try/catch. - try { - maybeInstance = findHostInstance(this); - } catch (error) {} - - // If there is no host component beneath this we should fail silently. - // This is not an error; it could mean a class component rendered null. - if (maybeInstance == null) { - return; - } - - if (maybeInstance.canonical) { - if (__DEV__) { - console.error( - 'Warning: setNativeProps is not currently supported in Fabric', - ); - } - return; - } - - const nativeTag = - maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; - const viewConfig: ReactNativeBaseComponentViewConfig<> = - maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; - - const updatePayload = create(nativeProps, viewConfig.validAttributes); - - // Avoid the overhead of bridge calls if there's no update. - // This is an expensive no-op for Android, and causes an unnecessary - // view invalidation for certain components (eg RCTTextInput) on iOS. - if (updatePayload != null) { - UIManager.updateView( - nativeTag, - viewConfig.uiViewClassName, - updatePayload, - ); - } - } - } - - // eslint-disable-next-line no-unused-expressions - (ReactNativeComponent.prototype: NativeMethods); - - return ReactNativeComponent; -} diff --git a/packages/react-native-renderer/src/ReactNativeFiberHostComponent.js b/packages/react-native-renderer/src/ReactNativeFiberHostComponent.js index cad31637b4ea9..ba316e010c7a5 100644 --- a/packages/react-native-renderer/src/ReactNativeFiberHostComponent.js +++ b/packages/react-native-renderer/src/ReactNativeFiberHostComponent.js @@ -28,13 +28,6 @@ import { warnForStyleProps, } from './NativeMethodsMixinUtils'; -/** - * This component defines the same methods as NativeMethodsMixin but without the - * findNodeHandle wrapper. This wrapper is unnecessary for HostComponent views - * and would also result in a circular require.js dependency (since - * ReactNativeFiber depends on this component and NativeMethodsMixin depends on - * ReactNativeFiber). - */ class ReactNativeFiberHostComponent { _children: Array; _nativeTag: number; diff --git a/packages/react-native-renderer/src/ReactNativeRenderer.js b/packages/react-native-renderer/src/ReactNativeRenderer.js index 5c5b10fcf1cfa..c8ddd3457a18b 100644 --- a/packages/react-native-renderer/src/ReactNativeRenderer.js +++ b/packages/react-native-renderer/src/ReactNativeRenderer.js @@ -35,8 +35,6 @@ import ReactVersion from 'shared/ReactVersion'; // Module provided by RN: import {UIManager} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; -import NativeMethodsMixin from './NativeMethodsMixin'; -import ReactNativeComponent from './ReactNativeComponent'; import {getClosestInstanceFromNode} from './ReactNativeComponentTree'; import {getInspectorDataForViewTag} from './ReactNativeFiberInspector'; @@ -164,8 +162,6 @@ function computeComponentStackForErrorReporting(reactTag: number): string { const roots = new Map(); const ReactNativeRenderer: ReactNativeType = { - NativeComponent: ReactNativeComponent(findNodeHandle, findHostInstance), - // This is needed for implementation details of TouchableNativeFeedback // Remove this once TouchableNativeFeedback doesn't use cloneElement findHostInstance_DEPRECATED, @@ -235,8 +231,6 @@ const ReactNativeRenderer: ReactNativeType = { unstable_batchedUpdates: batchedUpdates, __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: { - // Used as a mixin in many createClass-based components - NativeMethodsMixin: NativeMethodsMixin(findNodeHandle, findHostInstance), computeComponentStackForErrorReporting, }, }; diff --git a/packages/react-native-renderer/src/ReactNativeTypes.js b/packages/react-native-renderer/src/ReactNativeTypes.js index 013058a996e97..7619625b1371f 100644 --- a/packages/react-native-renderer/src/ReactNativeTypes.js +++ b/packages/react-native-renderer/src/ReactNativeTypes.js @@ -8,7 +8,7 @@ * @flow */ -import React, {type ElementRef, type AbstractComponent} from 'react'; +import type {ElementRef, AbstractComponent} from 'react'; export type MeasureOnSuccessCallback = ( x: number, @@ -77,31 +77,6 @@ export type ReactNativeBaseComponentViewConfig< export type ViewConfigGetter = () => ReactNativeBaseComponentViewConfig<>; -/** - * Class only exists for its Flow type. - */ -class ReactNativeComponent extends React.Component { - blur(): void {} - focus(): void {} - measure(callback: MeasureOnSuccessCallback): void {} - measureInWindow(callback: MeasureInWindowOnSuccessCallback): void {} - measureLayout( - relativeToNativeNode: number | ElementRef>, - onSuccess: MeasureLayoutOnSuccessCallback, - onFail?: () => void, - ): void {} - setNativeProps(nativeProps: Object): void {} -} - -// This type is only used for FlowTests. It shouldn't be imported directly -export type _InternalReactNativeComponentClass = Class< - ReactNativeComponent, ->; - -/** - * This type keeps ReactNativeFiberHostComponent and NativeMethodsMixin in sync. - * It can also provide types for ReactNative applications that use NMM or refs. - */ export type NativeMethods = { blur(): void, focus(): void, @@ -116,28 +91,22 @@ export type NativeMethods = { ... }; -export type NativeMethodsMixinType = NativeMethods; export type HostComponent = AbstractComponent>; type SecretInternalsType = { - NativeMethodsMixin: NativeMethodsMixinType, computeComponentStackForErrorReporting(tag: number): string, // TODO (bvaughn) Decide which additional types to expose here? // And how much information to fill in for the above types. ... }; -type SecretInternalsFabricType = { - NativeMethodsMixin: NativeMethodsMixinType, - ... -}; +type SecretInternalsFabricType = {...}; /** * Flat ReactNative renderer bundles are too big for Flow to parse efficiently. * Provide minimal Flow typing for the high-level RN API and call it a day. */ export type ReactNativeType = { - NativeComponent: typeof ReactNativeComponent, findHostInstance_DEPRECATED( componentOrHandle: any, ): ?ElementRef>, @@ -157,7 +126,6 @@ export type ReactNativeType = { }; export type ReactFabricType = { - NativeComponent: typeof ReactNativeComponent, findHostInstance_DEPRECATED(componentOrHandle: any): ?HostComponent, findNodeHandle(componentOrHandle: any): ?number, dispatchCommand(handle: any, command: string, args: Array): void, diff --git a/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js index 51dd4ca835313..0929b80e36b56 100644 --- a/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js +++ b/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js @@ -13,11 +13,9 @@ let React; let ReactFabric; let ReactFeatureFlags; -let createReactClass; let createReactNativeComponentClass; let UIManager; let StrictMode; -let NativeMethodsMixin; const SET_NATIVE_PROPS_NOT_SUPPORTED_MESSAGE = 'Warning: setNativeProps is not currently supported in Fabric'; @@ -42,16 +40,8 @@ describe('ReactFabric', () => { ReactFeatureFlags = require('shared/ReactFeatureFlags'); UIManager = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface') .UIManager; - createReactClass = require('create-react-class/factory')( - React.Component, - React.isValidElement, - new React.Component().updater, - ); createReactNativeComponentClass = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface') .ReactNativeViewConfigRegistry.register; - NativeMethodsMixin = - ReactFabric.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED - .NativeMethodsMixin; }); it('should be able to create and render a native component', () => { @@ -213,49 +203,34 @@ describe('ReactFabric', () => { uiViewClassName: 'RCTView', })); - class Subclass extends ReactFabric.NativeComponent { - render() { - return ; - } - } + UIManager.updateView.mockReset(); - const CreateClass = createReactClass({ - mixins: [NativeMethodsMixin], - render: () => { - return ; - }, + let viewRef; + ReactFabric.render( + { + viewRef = ref; + }} + />, + 11, + ); + expect(UIManager.updateView).not.toBeCalled(); + + expect(() => { + viewRef.setNativeProps({}); + }).toErrorDev([SET_NATIVE_PROPS_NOT_SUPPORTED_MESSAGE], { + withoutStack: true, }); - [View, Subclass, CreateClass].forEach(Component => { - UIManager.updateView.mockReset(); + expect(UIManager.updateView).not.toBeCalled(); - let viewRef; - ReactFabric.render( - { - viewRef = ref; - }} - />, - 11, - ); - expect(UIManager.updateView).not.toBeCalled(); - - expect(() => { - viewRef.setNativeProps({}); - }).toErrorDev([SET_NATIVE_PROPS_NOT_SUPPORTED_MESSAGE], { - withoutStack: true, - }); - - expect(UIManager.updateView).not.toBeCalled(); - - expect(() => { - viewRef.setNativeProps({foo: 'baz'}); - }).toErrorDev([SET_NATIVE_PROPS_NOT_SUPPORTED_MESSAGE], { - withoutStack: true, - }); - expect(UIManager.updateView).not.toBeCalled(); + expect(() => { + viewRef.setNativeProps({foo: 'baz'}); + }).toErrorDev([SET_NATIVE_PROPS_NOT_SUPPORTED_MESSAGE], { + withoutStack: true, }); + expect(UIManager.updateView).not.toBeCalled(); }); it('should call dispatchCommand for native refs', () => { @@ -264,75 +239,53 @@ describe('ReactFabric', () => { uiViewClassName: 'RCTView', })); - [View].forEach(Component => { - nativeFabricUIManager.dispatchCommand.mockClear(); + nativeFabricUIManager.dispatchCommand.mockClear(); - let viewRef; - ReactFabric.render( - { - viewRef = ref; - }} - />, - 11, - ); + let viewRef; + ReactFabric.render( + { + viewRef = ref; + }} + />, + 11, + ); - expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled(); - ReactFabric.dispatchCommand(viewRef, 'updateCommand', [10, 20]); - expect(nativeFabricUIManager.dispatchCommand).toHaveBeenCalledTimes(1); - expect( - nativeFabricUIManager.dispatchCommand, - ).toHaveBeenCalledWith(expect.any(Object), 'updateCommand', [10, 20]); - }); + expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled(); + ReactFabric.dispatchCommand(viewRef, 'updateCommand', [10, 20]); + expect(nativeFabricUIManager.dispatchCommand).toHaveBeenCalledTimes(1); + expect( + nativeFabricUIManager.dispatchCommand, + ).toHaveBeenCalledWith(expect.any(Object), 'updateCommand', [10, 20]); }); it('should warn and no-op if calling dispatchCommand on non native refs', () => { - const View = createReactNativeComponentClass('RCTView', () => ({ - validAttributes: {foo: true}, - uiViewClassName: 'RCTView', - })); - class BasicClass extends React.Component { render() { return ; } } - class Subclass extends ReactFabric.NativeComponent { - render() { - return ; - } - } + nativeFabricUIManager.dispatchCommand.mockReset(); - const CreateClass = createReactClass({ - mixins: [NativeMethodsMixin], - render: () => { - return ; - }, - }); - - [BasicClass, Subclass, CreateClass].forEach(Component => { - nativeFabricUIManager.dispatchCommand.mockReset(); - - let viewRef; - ReactFabric.render( - { - viewRef = ref; - }} - />, - 11, - ); - - expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled(); - expect(() => { - ReactFabric.dispatchCommand(viewRef, 'updateCommand', [10, 20]); - }).toErrorDev([DISPATCH_COMMAND_REQUIRES_HOST_COMPONENT], { - withoutStack: true, - }); + let viewRef; + ReactFabric.render( + { + viewRef = ref; + }} + />, + 11, + ); - expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled(); + expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled(); + expect(() => { + ReactFabric.dispatchCommand(viewRef, 'updateCommand', [10, 20]); + }).toErrorDev([DISPATCH_COMMAND_REQUIRES_HOST_COMPONENT], { + withoutStack: true, }); + + expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled(); }); it('should call FabricUIManager.measure on ref.measure', () => { @@ -341,39 +294,24 @@ describe('ReactFabric', () => { uiViewClassName: 'RCTView', })); - class Subclass extends ReactFabric.NativeComponent { - render() { - return {this.props.children}; - } - } - - const CreateClass = createReactClass({ - mixins: [NativeMethodsMixin], - render() { - return {this.props.children}; - }, - }); - - [View, Subclass, CreateClass].forEach(Component => { - nativeFabricUIManager.measure.mockClear(); + nativeFabricUIManager.measure.mockClear(); - let viewRef; - ReactFabric.render( - { - viewRef = ref; - }} - />, - 11, - ); + let viewRef; + ReactFabric.render( + { + viewRef = ref; + }} + />, + 11, + ); - expect(nativeFabricUIManager.measure).not.toBeCalled(); - const successCallback = jest.fn(); - viewRef.measure(successCallback); - expect(nativeFabricUIManager.measure).toHaveBeenCalledTimes(1); - expect(successCallback).toHaveBeenCalledTimes(1); - expect(successCallback).toHaveBeenCalledWith(10, 10, 100, 100, 0, 0); - }); + expect(nativeFabricUIManager.measure).not.toBeCalled(); + const successCallback = jest.fn(); + viewRef.measure(successCallback); + expect(nativeFabricUIManager.measure).toHaveBeenCalledTimes(1); + expect(successCallback).toHaveBeenCalledTimes(1); + expect(successCallback).toHaveBeenCalledWith(10, 10, 100, 100, 0, 0); }); it('should call FabricUIManager.measureInWindow on ref.measureInWindow', () => { @@ -382,39 +320,24 @@ describe('ReactFabric', () => { uiViewClassName: 'RCTView', })); - class Subclass extends ReactFabric.NativeComponent { - render() { - return {this.props.children}; - } - } + nativeFabricUIManager.measureInWindow.mockClear(); - const CreateClass = createReactClass({ - mixins: [NativeMethodsMixin], - render() { - return {this.props.children}; - }, - }); - - [View, Subclass, CreateClass].forEach(Component => { - nativeFabricUIManager.measureInWindow.mockClear(); - - let viewRef; - ReactFabric.render( - { - viewRef = ref; - }} - />, - 11, - ); + let viewRef; + ReactFabric.render( + { + viewRef = ref; + }} + />, + 11, + ); - expect(nativeFabricUIManager.measureInWindow).not.toBeCalled(); - const successCallback = jest.fn(); - viewRef.measureInWindow(successCallback); - expect(nativeFabricUIManager.measureInWindow).toHaveBeenCalledTimes(1); - expect(successCallback).toHaveBeenCalledTimes(1); - expect(successCallback).toHaveBeenCalledWith(10, 10, 100, 100); - }); + expect(nativeFabricUIManager.measureInWindow).not.toBeCalled(); + const successCallback = jest.fn(); + viewRef.measureInWindow(successCallback); + expect(nativeFabricUIManager.measureInWindow).toHaveBeenCalledTimes(1); + expect(successCallback).toHaveBeenCalledTimes(1); + expect(successCallback).toHaveBeenCalledWith(10, 10, 100, 100); }); it('should support ref in ref.measureLayout', () => { @@ -423,98 +346,34 @@ describe('ReactFabric', () => { uiViewClassName: 'RCTView', })); - [View].forEach(Component => { - nativeFabricUIManager.measureLayout.mockClear(); - - let viewRef; - let otherRef; - ReactFabric.render( - - { - viewRef = ref; - }} - /> - { - otherRef = ref; - }} - /> - , - 11, - ); - - expect(nativeFabricUIManager.measureLayout).not.toBeCalled(); - const successCallback = jest.fn(); - const failureCallback = jest.fn(); - viewRef.measureLayout(otherRef, successCallback, failureCallback); - expect(nativeFabricUIManager.measureLayout).toHaveBeenCalledTimes(1); - expect(successCallback).toHaveBeenCalledTimes(1); - expect(successCallback).toHaveBeenCalledWith(1, 1, 100, 100); - }); - }); + nativeFabricUIManager.measureLayout.mockClear(); - it('should warn when calling measureLayout on Subclass and NativeMethodsMixin', () => { - const View = createReactNativeComponentClass('RCTView', () => ({ - validAttributes: {foo: true}, - uiViewClassName: 'RCTView', - })); - - class Subclass extends ReactFabric.NativeComponent { - render() { - return {this.props.children}; - } - } - - const CreateClass = createReactClass({ - mixins: [NativeMethodsMixin], - render() { - return {this.props.children}; - }, - }); - - [Subclass, CreateClass].forEach(Component => { - nativeFabricUIManager.measureLayout.mockReset(); - - let viewRef; - let otherRef; - ReactFabric.render( - - { - viewRef = ref; - }} - /> - { - otherRef = ref; - }} - /> - , - 11, - ); - - const successCallback = jest.fn(); - const failureCallback = jest.fn(); - - expect(() => { - viewRef.measureLayout(otherRef, successCallback, failureCallback); - }).toErrorDev( - [ - 'Warning: measureLayout on components using NativeMethodsMixin ' + - 'or ReactNative.NativeComponent is not currently supported in Fabric. ' + - 'measureLayout must be called on a native ref. Consider using forwardRef.', - ], - { - withoutStack: true, - }, - ); + let viewRef; + let otherRef; + ReactFabric.render( + + { + viewRef = ref; + }} + /> + { + otherRef = ref; + }} + /> + , + 11, + ); - expect(nativeFabricUIManager.measureLayout).not.toBeCalled(); - expect(UIManager.measureLayout).not.toBeCalled(); - }); + expect(nativeFabricUIManager.measureLayout).not.toBeCalled(); + const successCallback = jest.fn(); + const failureCallback = jest.fn(); + viewRef.measureLayout(otherRef, successCallback, failureCallback); + expect(nativeFabricUIManager.measureLayout).toHaveBeenCalledTimes(1); + expect(successCallback).toHaveBeenCalledTimes(1); + expect(successCallback).toHaveBeenCalledWith(1, 1, 100, 100); }); it('returns the correct instance and calls it in the callback', () => { diff --git a/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js index ac38fcfe2facc..395cac0c20d8c 100644 --- a/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js +++ b/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js @@ -13,10 +13,8 @@ let React; let StrictMode; let ReactNative; -let createReactClass; let createReactNativeComponentClass; let UIManager; -let NativeMethodsMixin; const DISPATCH_COMMAND_REQUIRES_HOST_COMPONENT = "Warning: dispatchCommand was called with a ref that isn't a " + @@ -31,16 +29,8 @@ describe('ReactNative', () => { ReactNative = require('react-native-renderer'); UIManager = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface') .UIManager; - createReactClass = require('create-react-class/factory')( - React.Component, - React.isValidElement, - new React.Component().updater, - ); createReactNativeComponentClass = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface') .ReactNativeViewConfigRegistry.register; - NativeMethodsMixin = - ReactNative.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED - .NativeMethodsMixin; }); it('should be able to create and render a native component', () => { @@ -109,75 +99,53 @@ describe('ReactNative', () => { uiViewClassName: 'RCTView', })); - [View].forEach(Component => { - UIManager.dispatchViewManagerCommand.mockClear(); + UIManager.dispatchViewManagerCommand.mockClear(); - let viewRef; - ReactNative.render( - { - viewRef = ref; - }} - />, - 11, - ); + let viewRef; + ReactNative.render( + { + viewRef = ref; + }} + />, + 11, + ); - expect(UIManager.dispatchViewManagerCommand).not.toBeCalled(); - ReactNative.dispatchCommand(viewRef, 'updateCommand', [10, 20]); - expect(UIManager.dispatchViewManagerCommand).toHaveBeenCalledTimes(1); - expect( - UIManager.dispatchViewManagerCommand, - ).toHaveBeenCalledWith(expect.any(Number), 'updateCommand', [10, 20]); - }); + expect(UIManager.dispatchViewManagerCommand).not.toBeCalled(); + ReactNative.dispatchCommand(viewRef, 'updateCommand', [10, 20]); + expect(UIManager.dispatchViewManagerCommand).toHaveBeenCalledTimes(1); + expect( + UIManager.dispatchViewManagerCommand, + ).toHaveBeenCalledWith(expect.any(Number), 'updateCommand', [10, 20]); }); it('should warn and no-op if calling dispatchCommand on non native refs', () => { - const View = createReactNativeComponentClass('RCTView', () => ({ - validAttributes: {foo: true}, - uiViewClassName: 'RCTView', - })); - class BasicClass extends React.Component { render() { return ; } } - class Subclass extends ReactNative.NativeComponent { - render() { - return ; - } - } - - const CreateClass = createReactClass({ - mixins: [NativeMethodsMixin], - render: () => { - return ; - }, - }); - - [BasicClass, Subclass, CreateClass].forEach(Component => { - UIManager.dispatchViewManagerCommand.mockReset(); + UIManager.dispatchViewManagerCommand.mockReset(); - let viewRef; - ReactNative.render( - { - viewRef = ref; - }} - />, - 11, - ); - - expect(UIManager.dispatchViewManagerCommand).not.toBeCalled(); - expect(() => { - ReactNative.dispatchCommand(viewRef, 'updateCommand', [10, 20]); - }).toErrorDev([DISPATCH_COMMAND_REQUIRES_HOST_COMPONENT], { - withoutStack: true, - }); + let viewRef; + ReactNative.render( + { + viewRef = ref; + }} + />, + 11, + ); - expect(UIManager.dispatchViewManagerCommand).not.toBeCalled(); + expect(UIManager.dispatchViewManagerCommand).not.toBeCalled(); + expect(() => { + ReactNative.dispatchCommand(viewRef, 'updateCommand', [10, 20]); + }).toErrorDev([DISPATCH_COMMAND_REQUIRES_HOST_COMPONENT], { + withoutStack: true, }); + + expect(UIManager.dispatchViewManagerCommand).not.toBeCalled(); }); it('should not call UIManager.updateView from ref.setNativeProps for properties that have not changed', () => { @@ -186,46 +154,31 @@ describe('ReactNative', () => { uiViewClassName: 'RCTView', })); - class Subclass extends ReactNative.NativeComponent { - render() { - return ; - } - } + UIManager.updateView.mockReset(); - const CreateClass = createReactClass({ - mixins: [NativeMethodsMixin], - render: () => { - return ; - }, - }); - - [View, Subclass, CreateClass].forEach(Component => { - UIManager.updateView.mockReset(); - - let viewRef; - ReactNative.render( - { - viewRef = ref; - }} - />, - 11, - ); + let viewRef; + ReactNative.render( + { + viewRef = ref; + }} + />, + 11, + ); - expect(UIManager.updateView).not.toBeCalled(); + expect(UIManager.updateView).not.toBeCalled(); - viewRef.setNativeProps({}); - expect(UIManager.updateView).not.toBeCalled(); + viewRef.setNativeProps({}); + expect(UIManager.updateView).not.toBeCalled(); - viewRef.setNativeProps({foo: 'baz'}); - expect(UIManager.updateView).toHaveBeenCalledTimes(1); - expect(UIManager.updateView).toHaveBeenCalledWith( - expect.any(Number), - 'RCTView', - {foo: 'baz'}, - ); - }); + viewRef.setNativeProps({foo: 'baz'}); + expect(UIManager.updateView).toHaveBeenCalledTimes(1); + expect(UIManager.updateView).toHaveBeenCalledWith( + expect.any(Number), + 'RCTView', + {foo: 'baz'}, + ); }); it('should call UIManager.measure on ref.measure', () => { @@ -234,39 +187,24 @@ describe('ReactNative', () => { uiViewClassName: 'RCTView', })); - class Subclass extends ReactNative.NativeComponent { - render() { - return {this.props.children}; - } - } + UIManager.measure.mockClear(); - const CreateClass = createReactClass({ - mixins: [NativeMethodsMixin], - render() { - return {this.props.children}; - }, - }); - - [View, Subclass, CreateClass].forEach(Component => { - UIManager.measure.mockClear(); + let viewRef; + ReactNative.render( + { + viewRef = ref; + }} + />, + 11, + ); - let viewRef; - ReactNative.render( - { - viewRef = ref; - }} - />, - 11, - ); - - expect(UIManager.measure).not.toBeCalled(); - const successCallback = jest.fn(); - viewRef.measure(successCallback); - expect(UIManager.measure).toHaveBeenCalledTimes(1); - expect(successCallback).toHaveBeenCalledTimes(1); - expect(successCallback).toHaveBeenCalledWith(10, 10, 100, 100, 0, 0); - }); + expect(UIManager.measure).not.toBeCalled(); + const successCallback = jest.fn(); + viewRef.measure(successCallback); + expect(UIManager.measure).toHaveBeenCalledTimes(1); + expect(successCallback).toHaveBeenCalledTimes(1); + expect(successCallback).toHaveBeenCalledWith(10, 10, 100, 100, 0, 0); }); it('should call UIManager.measureInWindow on ref.measureInWindow', () => { @@ -275,39 +213,24 @@ describe('ReactNative', () => { uiViewClassName: 'RCTView', })); - class Subclass extends ReactNative.NativeComponent { - render() { - return {this.props.children}; - } - } - - const CreateClass = createReactClass({ - mixins: [NativeMethodsMixin], - render() { - return {this.props.children}; - }, - }); + UIManager.measureInWindow.mockClear(); - [View, Subclass, CreateClass].forEach(Component => { - UIManager.measureInWindow.mockClear(); + let viewRef; + ReactNative.render( + { + viewRef = ref; + }} + />, + 11, + ); - let viewRef; - ReactNative.render( - { - viewRef = ref; - }} - />, - 11, - ); - - expect(UIManager.measureInWindow).not.toBeCalled(); - const successCallback = jest.fn(); - viewRef.measureInWindow(successCallback); - expect(UIManager.measureInWindow).toHaveBeenCalledTimes(1); - expect(successCallback).toHaveBeenCalledTimes(1); - expect(successCallback).toHaveBeenCalledWith(10, 10, 100, 100); - }); + expect(UIManager.measureInWindow).not.toBeCalled(); + const successCallback = jest.fn(); + viewRef.measureInWindow(successCallback); + expect(UIManager.measureInWindow).toHaveBeenCalledTimes(1); + expect(successCallback).toHaveBeenCalledTimes(1); + expect(successCallback).toHaveBeenCalledWith(10, 10, 100, 100); }); it('should support reactTag in ref.measureLayout', () => { @@ -316,53 +239,38 @@ describe('ReactNative', () => { uiViewClassName: 'RCTView', })); - class Subclass extends ReactNative.NativeComponent { - render() { - return {this.props.children}; - } - } - - const CreateClass = createReactClass({ - mixins: [NativeMethodsMixin], - render() { - return {this.props.children}; - }, - }); + UIManager.measureLayout.mockClear(); - [View, Subclass, CreateClass].forEach(Component => { - UIManager.measureLayout.mockClear(); + let viewRef; + let otherRef; + ReactNative.render( + + { + viewRef = ref; + }} + /> + { + otherRef = ref; + }} + /> + , + 11, + ); - let viewRef; - let otherRef; - ReactNative.render( - - { - viewRef = ref; - }} - /> - { - otherRef = ref; - }} - /> - , - 11, - ); - - expect(UIManager.measureLayout).not.toBeCalled(); - const successCallback = jest.fn(); - const failureCallback = jest.fn(); - viewRef.measureLayout( - ReactNative.findNodeHandle(otherRef), - successCallback, - failureCallback, - ); - expect(UIManager.measureLayout).toHaveBeenCalledTimes(1); - expect(successCallback).toHaveBeenCalledTimes(1); - expect(successCallback).toHaveBeenCalledWith(1, 1, 100, 100); - }); + expect(UIManager.measureLayout).not.toBeCalled(); + const successCallback = jest.fn(); + const failureCallback = jest.fn(); + viewRef.measureLayout( + ReactNative.findNodeHandle(otherRef), + successCallback, + failureCallback, + ); + expect(UIManager.measureLayout).toHaveBeenCalledTimes(1); + expect(successCallback).toHaveBeenCalledTimes(1); + expect(successCallback).toHaveBeenCalledWith(1, 1, 100, 100); }); it('should support ref in ref.measureLayout of host components', () => { @@ -371,36 +279,34 @@ describe('ReactNative', () => { uiViewClassName: 'RCTView', })); - [View].forEach(Component => { - UIManager.measureLayout.mockClear(); + UIManager.measureLayout.mockClear(); - let viewRef; - let otherRef; - ReactNative.render( - - { - viewRef = ref; - }} - /> - { - otherRef = ref; - }} - /> - , - 11, - ); - - expect(UIManager.measureLayout).not.toBeCalled(); - const successCallback = jest.fn(); - const failureCallback = jest.fn(); - viewRef.measureLayout(otherRef, successCallback, failureCallback); - expect(UIManager.measureLayout).toHaveBeenCalledTimes(1); - expect(successCallback).toHaveBeenCalledTimes(1); - expect(successCallback).toHaveBeenCalledWith(1, 1, 100, 100); - }); + let viewRef; + let otherRef; + ReactNative.render( + + { + viewRef = ref; + }} + /> + { + otherRef = ref; + }} + /> + , + 11, + ); + + expect(UIManager.measureLayout).not.toBeCalled(); + const successCallback = jest.fn(); + const failureCallback = jest.fn(); + viewRef.measureLayout(otherRef, successCallback, failureCallback); + expect(UIManager.measureLayout).toHaveBeenCalledTimes(1); + expect(successCallback).toHaveBeenCalledTimes(1); + expect(successCallback).toHaveBeenCalledWith(1, 1, 100, 100); }); it('returns the correct instance and calls it in the callback', () => { diff --git a/packages/react/src/__tests__/createReactClassIntegration-test.internal.js b/packages/react/src/__tests__/createReactClassIntegration-test.internal.js deleted file mode 100644 index 3ea37ce80a373..0000000000000 --- a/packages/react/src/__tests__/createReactClassIntegration-test.internal.js +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @emails react-core - */ - -'use strict'; - -describe('create-react-class-integration', () => { - describe('ReactNative NativeMethodsMixin', () => { - let React; - let ReactNative; - let NativeMethodsMixin; - let createReactClass; - - beforeEach(() => { - jest.resetModules(); - - React = require('react'); - - createReactClass = require('create-react-class/factory')( - React.Component, - React.isValidElement, - new React.Component().updater, - ); - - ReactNative = require('react-native-renderer'); - NativeMethodsMixin = - ReactNative.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED - .NativeMethodsMixin; - }); - - it('should not warn about default DEV-only legacy lifecycle methods', () => { - const View = createReactClass({ - mixins: [NativeMethodsMixin], - render: () => null, - }); - - ReactNative.render(, 1); - }); - - it('should warn if users specify their own legacy componentWillMount', () => { - const View = createReactClass({ - displayName: 'MyNativeComponent', - mixins: [NativeMethodsMixin], - componentWillMount: () => {}, - render: () => null, - }); - - expect(() => - ReactNative.render(, 1), - ).toWarnDev('componentWillMount has been renamed', {withoutStack: true}); - }); - - it('should warn if users specify their own legacy componentWillReceiveProps', () => { - const View = createReactClass({ - displayName: 'MyNativeComponent', - mixins: [NativeMethodsMixin], - componentWillReceiveProps: () => {}, - render: () => null, - }); - - expect(() => ReactNative.render(, 1)).toWarnDev( - 'componentWillReceiveProps has been renamed', - { - withoutStack: true, - }, - ); - }); - }); -}); diff --git a/scripts/rollup/shims/react-native/NativeMethodsMixin.js b/scripts/rollup/shims/react-native/NativeMethodsMixin.js deleted file mode 100644 index c50f379fde06c..0000000000000 --- a/scripts/rollup/shims/react-native/NativeMethodsMixin.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - * @flow - */ - -'use strict'; - -const { - __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, -} = require('./ReactNative'); - -import type {NativeMethodsMixinType} from './ReactNativeTypes'; - -const {NativeMethodsMixin} = __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; - -module.exports = ((NativeMethodsMixin: any): $Exact);