diff --git a/packages/react-native-renderer/src/ReactFabricComponentTree.js b/packages/react-native-renderer/src/ReactFabricComponentTree.js index 4cdb1ca81505c..8ecfe33904269 100644 --- a/packages/react-native-renderer/src/ReactFabricComponentTree.js +++ b/packages/react-native-renderer/src/ReactFabricComponentTree.js @@ -20,6 +20,15 @@ import {getPublicInstance} from './ReactFabricHostConfig'; // This is ok in DOM because they types are interchangeable, but in React Native // they aren't. function getInstanceFromNode(node: Instance | TextInstance): Fiber | null { + const instance: Instance = (node: $FlowFixMe); // In React Native, node is never a text instance + + if ( + instance.internals != null && + instance.internals.internalInstanceHandle != null + ) { + return instance.internals.internalInstanceHandle; + } + // $FlowFixMe[incompatible-return] DevTools incorrectly passes a fiber in React Native. return node; } @@ -35,7 +44,7 @@ function getNodeFromInstance(fiber: Fiber): PublicInstance { } function getFiberCurrentPropsFromNode(instance: Instance): Props { - return instance.canonical.currentProps; + return instance && instance.internals && instance.internals.currentProps; } export { diff --git a/packages/react-native-renderer/src/ReactFabricHostConfig.js b/packages/react-native-renderer/src/ReactFabricHostConfig.js index 09cb55a572fcd..12a10bf79fd15 100644 --- a/packages/react-native-renderer/src/ReactFabricHostConfig.js +++ b/packages/react-native-renderer/src/ReactFabricHostConfig.js @@ -7,22 +7,13 @@ * @flow */ -import type {ElementRef} from 'react'; -import type { - HostComponent, - MeasureInWindowOnSuccessCallback, - MeasureLayoutOnSuccessCallback, - MeasureOnSuccessCallback, - NativeMethods, - ViewConfig, - TouchedViewDataAtPoint, -} from './ReactNativeTypes'; - -import {warnForStyleProps} from './NativeMethodsMixinUtils'; +import type {TouchedViewDataAtPoint, ViewConfig} from './ReactNativeTypes'; +import { + createPublicInstance, + type ReactFabricHostComponent, +} from './ReactFabricPublicInstance'; import {create, diff} from './ReactNativeAttributePayload'; - import {dispatchEvent} from './ReactFabricEventEmitter'; - import { DefaultEventPriority, DiscreteEventPriority, @@ -31,7 +22,6 @@ import { // Modules provided by RN: import { ReactNativeViewConfigRegistry, - TextInputState, deepFreezeAndThrowOnMutationInDev, } from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; @@ -46,14 +36,9 @@ const { appendChildToSet: appendChildNodeToSet, completeRoot, registerEventHandler, - measure: fabricMeasure, - measureInWindow: fabricMeasureInWindow, - measureLayout: fabricMeasureLayout, unstable_DefaultEventPriority: FabricDefaultPriority, unstable_DiscreteEventPriority: FabricDiscretePriority, unstable_getCurrentEventPriority: fabricGetCurrentEventPriority, - setNativeProps, - getBoundingClientRect: fabricGetBoundingClientRect, } = nativeFabricUIManager; const {get: getViewConfigForType} = ReactNativeViewConfigRegistry; @@ -68,9 +53,18 @@ type Node = Object; export type Type = string; export type Props = Object; export type Instance = { + // Reference to the shadow node. node: Node, - canonical: ReactFabricHostComponent, - ... + // Exposed through refs. + publicInstance: ReactFabricHostComponent, + // We define this as an object instead of as separate fields to simplify + // making copies of instance where `internals` don't change. + internals: { + nativeTag: number, + viewConfig: ViewConfig, + currentProps: Props, + internalInstanceHandle: Object, + }, }; export type TextInstance = {node: Node, ...}; export type HydratableInstance = Instance | TextInstance; @@ -104,137 +98,6 @@ if (registerEventHandler) { registerEventHandler(dispatchEvent); } -const noop = () => {}; - -/** - * This is used for refs on host components. - */ -class ReactFabricHostComponent implements NativeMethods { - _nativeTag: number; - viewConfig: ViewConfig; - currentProps: Props; - _internalInstanceHandle: Object; - - constructor( - tag: number, - viewConfig: ViewConfig, - props: Props, - internalInstanceHandle: Object, - ) { - this._nativeTag = tag; - this.viewConfig = viewConfig; - this.currentProps = props; - this._internalInstanceHandle = internalInstanceHandle; - } - - blur() { - TextInputState.blurTextInput(this); - } - - focus() { - TextInputState.focusTextInput(this); - } - - measure(callback: MeasureOnSuccessCallback) { - const node = getShadowNodeFromInternalInstanceHandle( - this._internalInstanceHandle, - ); - if (node != null) { - fabricMeasure(node, callback); - } - } - - measureInWindow(callback: MeasureInWindowOnSuccessCallback) { - const node = getShadowNodeFromInternalInstanceHandle( - this._internalInstanceHandle, - ); - if (node != null) { - fabricMeasureInWindow(node, callback); - } - } - - measureLayout( - relativeToNativeNode: number | ElementRef>, - onSuccess: MeasureLayoutOnSuccessCallback, - onFail?: () => void /* currently unused */, - ) { - if ( - typeof relativeToNativeNode === 'number' || - !(relativeToNativeNode instanceof ReactFabricHostComponent) - ) { - if (__DEV__) { - console.error( - 'Warning: ref.measureLayout must be called with a ref to a native component.', - ); - } - - return; - } - - const toStateNode = getShadowNodeFromInternalInstanceHandle( - this._internalInstanceHandle, - ); - const fromStateNode = getShadowNodeFromInternalInstanceHandle( - relativeToNativeNode._internalInstanceHandle, - ); - - if (toStateNode != null && fromStateNode != null) { - fabricMeasureLayout( - toStateNode, - fromStateNode, - onFail != null ? onFail : noop, - onSuccess != null ? onSuccess : noop, - ); - } - } - - unstable_getBoundingClientRect(): DOMRect { - const node = getShadowNodeFromInternalInstanceHandle( - this._internalInstanceHandle, - ); - if (node != null) { - const rect = fabricGetBoundingClientRect(node); - - if (rect) { - return new DOMRect(rect[0], rect[1], rect[2], rect[3]); - } - } - - // Empty rect if any of the above failed - return new DOMRect(0, 0, 0, 0); - } - - setNativeProps(nativeProps: Object) { - if (__DEV__) { - warnForStyleProps(nativeProps, this.viewConfig.validAttributes); - } - const updatePayload = create(nativeProps, this.viewConfig.validAttributes); - - const node = getShadowNodeFromInternalInstanceHandle( - this._internalInstanceHandle, - ); - if (node != null && updatePayload != null) { - setNativeProps(node, updatePayload); - } - } -} - -type ParamOf = $Call<((arg: T) => mixed) => T, Fn>; -type ShadowNode = ParamOf<(typeof nativeFabricUIManager)['measure']>; - -export function getShadowNodeFromInternalInstanceHandle( - internalInstanceHandle: mixed, -): ?ShadowNode { - return ( - // $FlowExpectedError[incompatible-return] internalInstanceHandle is opaque but we need to make an exception here. - internalInstanceHandle && - // $FlowExpectedError[incompatible-return] - internalInstanceHandle.stateNode && - // $FlowExpectedError[incompatible-use] - internalInstanceHandle.stateNode.node - ); -} - export * from 'react-reconciler/src/ReactFiberHostConfigWithNoMutation'; export * from 'react-reconciler/src/ReactFiberHostConfigWithNoHydration'; export * from 'react-reconciler/src/ReactFiberHostConfigWithNoScopes'; @@ -280,16 +143,21 @@ export function createInstance( internalInstanceHandle, // internalInstanceHandle ); - const component = new ReactFabricHostComponent( + const component = createPublicInstance( tag, viewConfig, - props, internalInstanceHandle, ); return { node: node, - canonical: component, + publicInstance: component, + internals: { + nativeTag: tag, + viewConfig, + currentProps: props, + internalInstanceHandle, + }, }; } @@ -359,12 +227,15 @@ export function getChildHostContext( } export function getPublicInstance(instance: Instance): null | PublicInstance { - if (instance.canonical) { - return instance.canonical; + if (instance.publicInstance != null) { + return instance.publicInstance; } - // For compatibility with Paper + // For compatibility with the legacy renderer, in case it's used with Fabric + // in the same app. + // $FlowExpectedError[prop-missing] if (instance._nativeTag != null) { + // $FlowExpectedError[incompatible-return] return instance; } @@ -383,12 +254,12 @@ export function prepareUpdate( newProps: Props, hostContext: HostContext, ): null | Object { - const viewConfig = instance.canonical.viewConfig; + const viewConfig = instance.internals.viewConfig; const updatePayload = diff(oldProps, newProps, viewConfig.validAttributes); // TODO: If the event handlers have changed, we need to update the current props // in the commit phase but there is no host config hook to do it yet. // So instead we hack it by updating it in the render phase. - instance.canonical.currentProps = newProps; + instance.internals.currentProps = newProps; return updatePayload; } @@ -467,7 +338,8 @@ export function cloneInstance( } return { node: clone, - canonical: instance.canonical, + publicInstance: instance.publicInstance, + internals: instance.internals, }; } @@ -477,7 +349,7 @@ export function cloneHiddenInstance( props: Props, internalInstanceHandle: Object, ): Instance { - const viewConfig = instance.canonical.viewConfig; + const viewConfig = instance.internals.viewConfig; const node = instance.node; const updatePayload = create( {style: {display: 'none'}}, @@ -485,7 +357,8 @@ export function cloneHiddenInstance( ); return { node: cloneNodeWithNewProps(node, updatePayload), - canonical: instance.canonical, + publicInstance: instance.publicInstance, + internals: instance.internals, }; } diff --git a/packages/react-native-renderer/src/ReactFabricPublicInstance.js b/packages/react-native-renderer/src/ReactFabricPublicInstance.js new file mode 100644 index 0000000000000..9cca777b54905 --- /dev/null +++ b/packages/react-native-renderer/src/ReactFabricPublicInstance.js @@ -0,0 +1,154 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + */ + +import type {ElementRef} from 'react'; +import type { + ViewConfig, + NativeMethods, + HostComponent, + MeasureInWindowOnSuccessCallback, + MeasureLayoutOnSuccessCallback, + MeasureOnSuccessCallback, +} from './ReactNativeTypes'; + +import {TextInputState} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; +import {create} from './ReactNativeAttributePayload'; +import {getShadowNodeFromInternalInstanceHandle} from './ReactFabricPublicInstanceUtils'; + +import {warnForStyleProps} from './NativeMethodsMixinUtils'; + +const { + measure: fabricMeasure, + measureInWindow: fabricMeasureInWindow, + measureLayout: fabricMeasureLayout, + setNativeProps, + getBoundingClientRect: fabricGetBoundingClientRect, +} = nativeFabricUIManager; + +const noop = () => {}; + +/** + * This is used for refs on host components. + */ +export class ReactFabricHostComponent implements NativeMethods { + // These need to be accessible from `ReactFabricPublicInstanceUtils`. + __nativeTag: number; + __internalInstanceHandle: mixed; + + _viewConfig: ViewConfig; + + constructor( + tag: number, + viewConfig: ViewConfig, + internalInstanceHandle: mixed, + ) { + this.__nativeTag = tag; + this._viewConfig = viewConfig; + this.__internalInstanceHandle = internalInstanceHandle; + } + + blur() { + TextInputState.blurTextInput(this); + } + + focus() { + TextInputState.focusTextInput(this); + } + + measure(callback: MeasureOnSuccessCallback) { + const node = getShadowNodeFromInternalInstanceHandle( + this.__internalInstanceHandle, + ); + if (node != null) { + fabricMeasure(node, callback); + } + } + + measureInWindow(callback: MeasureInWindowOnSuccessCallback) { + const node = getShadowNodeFromInternalInstanceHandle( + this.__internalInstanceHandle, + ); + if (node != null) { + fabricMeasureInWindow(node, callback); + } + } + + measureLayout( + relativeToNativeNode: number | ElementRef>, + onSuccess: MeasureLayoutOnSuccessCallback, + onFail?: () => void /* currently unused */, + ) { + if ( + typeof relativeToNativeNode === 'number' || + !(relativeToNativeNode instanceof ReactFabricHostComponent) + ) { + if (__DEV__) { + console.error( + 'Warning: ref.measureLayout must be called with a ref to a native component.', + ); + } + + return; + } + + const toStateNode = getShadowNodeFromInternalInstanceHandle( + this.__internalInstanceHandle, + ); + const fromStateNode = getShadowNodeFromInternalInstanceHandle( + relativeToNativeNode.__internalInstanceHandle, + ); + + if (toStateNode != null && fromStateNode != null) { + fabricMeasureLayout( + toStateNode, + fromStateNode, + onFail != null ? onFail : noop, + onSuccess != null ? onSuccess : noop, + ); + } + } + + unstable_getBoundingClientRect(): DOMRect { + const node = getShadowNodeFromInternalInstanceHandle( + this.__internalInstanceHandle, + ); + if (node != null) { + const rect = fabricGetBoundingClientRect(node); + + if (rect) { + return new DOMRect(rect[0], rect[1], rect[2], rect[3]); + } + } + + // Empty rect if any of the above failed + return new DOMRect(0, 0, 0, 0); + } + + setNativeProps(nativeProps: {...}): void { + if (__DEV__) { + warnForStyleProps(nativeProps, this._viewConfig.validAttributes); + } + const updatePayload = create(nativeProps, this._viewConfig.validAttributes); + + const node = getShadowNodeFromInternalInstanceHandle( + this.__internalInstanceHandle, + ); + if (node != null && updatePayload != null) { + setNativeProps(node, updatePayload); + } + } +} + +export function createPublicInstance( + tag: number, + viewConfig: ViewConfig, + internalInstanceHandle: mixed, +): ReactFabricHostComponent { + return new ReactFabricHostComponent(tag, viewConfig, internalInstanceHandle); +} diff --git a/packages/react-native-renderer/src/ReactFabricPublicInstanceUtils.js b/packages/react-native-renderer/src/ReactFabricPublicInstanceUtils.js new file mode 100644 index 0000000000000..8ffdced50f49a --- /dev/null +++ b/packages/react-native-renderer/src/ReactFabricPublicInstanceUtils.js @@ -0,0 +1,45 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + */ + +import type {ReactFabricHostComponent} from './ReactFabricPublicInstance'; + +/** + * IMPORTANT: This module is used in Paper and Fabric. It needs to be defined + * outside of `ReactFabricPublicInstance` because that module requires + * `nativeFabricUIManager` to be defined in the global scope (which does not + * happen in Paper). + */ + +type ParamOf = $Call<((arg: T) => mixed) => T, Fn>; +type ShadowNode = ParamOf<(typeof nativeFabricUIManager)['measure']>; + +export function getNativeTagFromPublicInstance( + publicInstance: ReactFabricHostComponent, +): number { + return publicInstance.__nativeTag; +} + +export function getInternalInstanceHandleFromPublicInstance( + publicInstance: ReactFabricHostComponent, +): mixed { + return publicInstance.__internalInstanceHandle; +} + +export function getShadowNodeFromInternalInstanceHandle( + internalInstanceHandle: mixed, +): ?ShadowNode { + return ( + // $FlowExpectedError[incompatible-return] internalInstanceHandle is opaque but we need to make an exception here. + internalInstanceHandle && + // $FlowExpectedError[incompatible-return] + internalInstanceHandle.stateNode && + // $FlowExpectedError[incompatible-use] + internalInstanceHandle.stateNode.node + ); +} diff --git a/packages/react-native-renderer/src/ReactNativeComponentTree.js b/packages/react-native-renderer/src/ReactNativeComponentTree.js index 3af3fa5a443f5..e223b048afba0 100644 --- a/packages/react-native-renderer/src/ReactNativeComponentTree.js +++ b/packages/react-native-renderer/src/ReactNativeComponentTree.js @@ -24,9 +24,10 @@ function getInstanceFromTag(tag) { function getTagFromInstance(inst) { let nativeInstance = inst.stateNode; let tag = nativeInstance._nativeTag; - if (tag === undefined) { - nativeInstance = nativeInstance.canonical; - tag = nativeInstance._nativeTag; + if (tag === undefined && nativeInstance.internals) { + // For compatibility with Fabric + tag = nativeInstance.internals.nativeTag; + nativeInstance = nativeInstance.publicInstance; } if (!tag) { diff --git a/packages/react-native-renderer/src/ReactNativeFiberInspector.js b/packages/react-native-renderer/src/ReactNativeFiberInspector.js index 7641e9314f00f..80dea8a434746 100644 --- a/packages/react-native-renderer/src/ReactNativeFiberInspector.js +++ b/packages/react-native-renderer/src/ReactNativeFiberInspector.js @@ -214,11 +214,12 @@ if (__DEV__) { } closestInstance = - internalInstanceHandle.stateNode.canonical._internalInstanceHandle; + internalInstanceHandle.stateNode.fabricInternals + .internalInstanceHandle; // Note: this is deprecated and we want to remove it ASAP. Keeping it here for React DevTools compatibility for now. const nativeViewTag = - internalInstanceHandle.stateNode.canonical._nativeTag; + internalInstanceHandle.stateNode.fabricInternals.nativeTag; nativeFabricUIManager.measure( internalInstanceHandle.stateNode.node, diff --git a/packages/react-native-renderer/src/ReactNativeHostConfig.js b/packages/react-native-renderer/src/ReactNativeHostConfig.js index a3b58315205f3..330875debaefd 100644 --- a/packages/react-native-renderer/src/ReactNativeHostConfig.js +++ b/packages/react-native-renderer/src/ReactNativeHostConfig.js @@ -218,8 +218,8 @@ export function getChildHostContext( export function getPublicInstance(instance: Instance): * { // $FlowExpectedError[prop-missing] For compatibility with Fabric - if (instance.canonical) { - return instance.canonical; + if (instance.publicInstance != null) { + return instance.publicInstance; } return instance; diff --git a/packages/react-native-renderer/src/ReactNativePublicCompat.js b/packages/react-native-renderer/src/ReactNativePublicCompat.js index 50fbf21d0abb1..26a960c3acf2c 100644 --- a/packages/react-native-renderer/src/ReactNativePublicCompat.js +++ b/packages/react-native-renderer/src/ReactNativePublicCompat.js @@ -23,6 +23,12 @@ import { import ReactSharedInternals from 'shared/ReactSharedInternals'; import getComponentNameFromType from 'shared/getComponentNameFromType'; +import { + getInternalInstanceHandleFromPublicInstance, + getNativeTagFromPublicInstance, + getShadowNodeFromInternalInstanceHandle, +} from './ReactFabricPublicInstanceUtils'; + const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; export function findHostInstance_DEPRECATED( @@ -45,19 +51,24 @@ export function findHostInstance_DEPRECATED( owner.stateNode._warnedAboutRefsInRender = true; } } + if (componentOrHandle == null) { return null; } - // $FlowFixMe Flow has hardcoded values for React DOM that don't work with RN + + // For compatibility with Fabric instances + if (componentOrHandle.publicInstance) { + // $FlowExpectedError[incompatible-return] Can't refine componentOrHandle as a Fabric instance + return componentOrHandle.publicInstance; + } + + // For compatibility with legacy renderer instances if (componentOrHandle._nativeTag) { - // $FlowFixMe Flow has hardcoded values for React DOM that don't work with RN + // $FlowExpectedError[incompatible-return] Necessary when running Flow on Fabric + // $FlowExpectedError[prop-missing] return componentOrHandle; } - // $FlowFixMe Flow has hardcoded values for React DOM that don't work with RN - if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) { - // $FlowFixMe Flow has hardcoded values for React DOM that don't work with RN - return componentOrHandle.canonical; - } + let hostInstance; if (__DEV__) { hostInstance = findHostInstanceWithWarning( @@ -68,6 +79,7 @@ export function findHostInstance_DEPRECATED( hostInstance = findHostInstance(componentOrHandle); } + // findHostInstance handles legacy vs. Fabric differences correctly return hostInstance; } @@ -89,19 +101,31 @@ export function findNodeHandle(componentOrHandle: any): ?number { owner.stateNode._warnedAboutRefsInRender = true; } } + if (componentOrHandle == null) { return null; } + if (typeof componentOrHandle === 'number') { // Already a node handle return componentOrHandle; } + + // For compatibility with legacy renderer instances if (componentOrHandle._nativeTag) { return componentOrHandle._nativeTag; } - if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) { - return componentOrHandle.canonical._nativeTag; + + // For compatibility with Fabric instances + if (componentOrHandle.publicInstance != null) { + const nativeTag = getNativeTagFromPublicInstance( + componentOrHandle.publicInstance, + ); + if (nativeTag != null) { + return nativeTag; + } } + let hostInstance; if (__DEV__) { hostInstance = findHostInstanceWithWarning( @@ -116,7 +140,14 @@ export function findNodeHandle(componentOrHandle: any): ?number { return hostInstance; } - return hostInstance._nativeTag; + // $FlowFixMe[prop-missing] For compatibility with legacy renderer instances + if (hostInstance._nativeTag != null) { + // $FlowFixMe[incompatible-return] + return hostInstance._nativeTag; + } + + // $FlowFixMe[incompatible-call] Necessary when running Flow on the legacy renderer + return getNativeTagFromPublicInstance(hostInstance); } export function dispatchCommand( @@ -124,7 +155,11 @@ export function dispatchCommand( command: string, args: Array, ) { - if (handle._nativeTag == null) { + const nativeTag = + handle._nativeTag != null + ? handle._nativeTag + : getNativeTagFromPublicInstance(handle); + if (nativeTag == null) { if (__DEV__) { console.error( "dispatchCommand was called with a ref that isn't a " + @@ -134,18 +169,27 @@ export function dispatchCommand( return; } - if (handle._internalInstanceHandle != null) { - const {stateNode} = handle._internalInstanceHandle; - if (stateNode != null) { - nativeFabricUIManager.dispatchCommand(stateNode.node, command, args); + const internalInstanceHandle = + getInternalInstanceHandleFromPublicInstance(handle); + + if (internalInstanceHandle != null) { + const node = getShadowNodeFromInternalInstanceHandle( + internalInstanceHandle, + ); + if (node != null) { + nativeFabricUIManager.dispatchCommand(node, command, args); } } else { - UIManager.dispatchViewManagerCommand(handle._nativeTag, command, args); + UIManager.dispatchViewManagerCommand(nativeTag, command, args); } } export function sendAccessibilityEvent(handle: any, eventType: string) { - if (handle._nativeTag == null) { + const nativeTag = + handle._nativeTag != null + ? handle._nativeTag + : getNativeTagFromPublicInstance(handle); + if (nativeTag == null) { if (__DEV__) { console.error( "sendAccessibilityEvent was called with a ref that isn't a " + @@ -155,12 +199,16 @@ export function sendAccessibilityEvent(handle: any, eventType: string) { return; } - if (handle._internalInstanceHandle != null) { - const {stateNode} = handle._internalInstanceHandle; - if (stateNode != null) { - nativeFabricUIManager.sendAccessibilityEvent(stateNode.node, eventType); + const internalInstanceHandle = + getInternalInstanceHandleFromPublicInstance(handle); + if (internalInstanceHandle != null) { + const node = getShadowNodeFromInternalInstanceHandle( + internalInstanceHandle, + ); + if (node != null) { + nativeFabricUIManager.sendAccessibilityEvent(node, eventType); } } else { - legacySendAccessibilityEvent(handle._nativeTag, eventType); + legacySendAccessibilityEvent(nativeTag, eventType); } } 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 2e5d41afa0212..da360ec546e3d 100644 --- a/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js +++ b/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js @@ -15,6 +15,7 @@ let ReactFabric; let createReactNativeComponentClass; let StrictMode; let act; +let getNativeTagFromPublicInstance; const DISPATCH_COMMAND_REQUIRES_HOST_COMPONENT = "Warning: dispatchCommand was called with a ref that isn't a " + @@ -40,6 +41,8 @@ describe('ReactFabric', () => { createReactNativeComponentClass = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface') .ReactNativeViewConfigRegistry.register; + getNativeTagFromPublicInstance = + require('../ReactFabricPublicInstanceUtils').getNativeTagFromPublicInstance; act = require('jest-react').act; }); @@ -931,7 +934,7 @@ describe('ReactFabric', () => { '\n in RCTView (at **)' + '\n in ContainsStrictModeChild (at **)', ]); - expect(match).toBe(child._nativeTag); + expect(match).toBe(getNativeTagFromPublicInstance(child)); }); it('findNodeHandle should warn if passed a component that is inside StrictMode', () => { @@ -968,7 +971,7 @@ describe('ReactFabric', () => { '\n in RCTView (at **)' + '\n in IsInStrictMode (at **)', ]); - expect(match).toBe(child._nativeTag); + expect(match).toBe(getNativeTagFromPublicInstance(child)); }); it('should no-op if calling sendAccessibilityEvent on unmounted refs', () => { diff --git a/packages/react-native-renderer/src/__tests__/ReactFabricAndNative-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactFabricAndNative-test.internal.js index e494701dd0038..fca6d00c72774 100644 --- a/packages/react-native-renderer/src/__tests__/ReactFabricAndNative-test.internal.js +++ b/packages/react-native-renderer/src/__tests__/ReactFabricAndNative-test.internal.js @@ -16,6 +16,7 @@ let ReactNative; let UIManager; let createReactNativeComponentClass; let ReactNativePrivateInterface; +let getNativeTagFromPublicInstance; describe('created with ReactFabric called with ReactNative', () => { beforeEach(() => { @@ -35,6 +36,8 @@ describe('created with ReactFabric called with ReactNative', () => { createReactNativeComponentClass = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface') .ReactNativeViewConfigRegistry.register; + getNativeTagFromPublicInstance = + require('../ReactFabricPublicInstanceUtils').getNativeTagFromPublicInstance; }); it('find Fabric instances with the RN renderer', () => { @@ -54,7 +57,7 @@ describe('created with ReactFabric called with ReactNative', () => { ReactFabric.render(, 11); const instance = ReactNative.findHostInstance_DEPRECATED(ref.current); - expect(instance._nativeTag).toBe(2); + expect(getNativeTagFromPublicInstance(instance)).toBe(2); }); it('find Fabric nodes with the RN renderer', () => {