Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 6 additions & 149 deletions packages/react-native-renderer/src/ReactFabric.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,13 @@
* @flow
*/

import type {HostComponent} from './ReactNativeTypes';
import type {ReactPortal, ReactNodeList} from 'shared/ReactTypes';
import type {ElementRef, Element, ElementType} from 'react';
import type {FiberRoot} from 'react-reconciler/src/ReactInternalTypes';

import './ReactFabricInjection';

import {
findHostInstance,
findHostInstanceWithWarning,
batchedUpdates as batchedUpdatesImpl,
discreteUpdates,
createContainer,
Expand All @@ -29,159 +26,19 @@ import {createPortal as createPortalImpl} from 'react-reconciler/src/ReactPortal
import {setBatchingImplementation} from './legacy-events/ReactGenericBatching';
import ReactVersion from 'shared/ReactVersion';

// Modules provided by RN:
import {
UIManager,
legacySendAccessibilityEvent,
} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';

import {getClosestInstanceFromNode} from './ReactFabricComponentTree';
import {
getInspectorDataForViewTag,
getInspectorDataForViewAtPoint,
getInspectorDataForInstance,
} from './ReactNativeFiberInspector';
import {LegacyRoot, ConcurrentRoot} from 'react-reconciler/src/ReactRootTags';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import getComponentNameFromType from 'shared/getComponentNameFromType';

const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;

function findHostInstance_DEPRECATED<TElementType: ElementType>(
componentOrHandle: ?(ElementRef<TElementType> | number),
): ?ElementRef<HostComponent<mixed>> {
if (__DEV__) {
const owner = ReactCurrentOwner.current;
if (owner !== null && owner.stateNode !== null) {
if (!owner.stateNode._warnedAboutRefsInRender) {
console.error(
'%s is accessing findNodeHandle inside its render(). ' +
'render() should be a pure function of props and state. It should ' +
'never access something that requires stale data from the previous ' +
'render, such as refs. Move this logic to componentDidMount and ' +
'componentDidUpdate instead.',
getComponentNameFromType(owner.type) || 'A component',
);
}

owner.stateNode._warnedAboutRefsInRender = true;
}
}
if (componentOrHandle == null) {
return null;
}
// $FlowFixMe Flow has hardcoded values for React DOM that don't work with RN
if (componentOrHandle._nativeTag) {
// $FlowFixMe Flow has hardcoded values for React DOM that don't work with RN
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(
componentOrHandle,
'findHostInstance_DEPRECATED',
);
} else {
hostInstance = findHostInstance(componentOrHandle);
}

return hostInstance;
}

function findNodeHandle(componentOrHandle: any): ?number {
if (__DEV__) {
const owner = ReactCurrentOwner.current;
if (owner !== null && owner.stateNode !== null) {
if (!owner.stateNode._warnedAboutRefsInRender) {
console.error(
'%s is accessing findNodeHandle inside its render(). ' +
'render() should be a pure function of props and state. It should ' +
'never access something that requires stale data from the previous ' +
'render, such as refs. Move this logic to componentDidMount and ' +
'componentDidUpdate instead.',
getComponentNameFromType(owner.type) || 'A component',
);
}

owner.stateNode._warnedAboutRefsInRender = true;
}
}
if (componentOrHandle == null) {
return null;
}
if (typeof componentOrHandle === 'number') {
// Already a node handle
return componentOrHandle;
}
if (componentOrHandle._nativeTag) {
return componentOrHandle._nativeTag;
}
if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) {
return componentOrHandle.canonical._nativeTag;
}
let hostInstance;
if (__DEV__) {
hostInstance = findHostInstanceWithWarning(
componentOrHandle,
'findNodeHandle',
);
} else {
hostInstance = findHostInstance(componentOrHandle);
}

if (hostInstance == null) {
return hostInstance;
}

return hostInstance._nativeTag;
}

function dispatchCommand(handle: any, command: string, args: Array<any>) {
if (handle._nativeTag == null) {
if (__DEV__) {
console.error(
"dispatchCommand was called with a ref that isn't a " +
'native component. Use React.forwardRef to get access to the underlying native component',
);
}
return;
}

if (handle._internalInstanceHandle != null) {
const {stateNode} = handle._internalInstanceHandle;
if (stateNode != null) {
nativeFabricUIManager.dispatchCommand(stateNode.node, command, args);
}
} else {
UIManager.dispatchViewManagerCommand(handle._nativeTag, command, args);
}
}

function sendAccessibilityEvent(handle: any, eventType: string) {
if (handle._nativeTag == null) {
if (__DEV__) {
console.error(
"sendAccessibilityEvent was called with a ref that isn't a " +
'native component. Use React.forwardRef to get access to the underlying native component',
);
}
return;
}

if (handle._internalInstanceHandle != null) {
const {stateNode} = handle._internalInstanceHandle;
if (stateNode != null) {
nativeFabricUIManager.sendAccessibilityEvent(stateNode.node, eventType);
}
} else {
legacySendAccessibilityEvent(handle._nativeTag, eventType);
}
}
import {
findHostInstance_DEPRECATED,
findNodeHandle,
dispatchCommand,
sendAccessibilityEvent,
} from './ReactNativePublicCompat';

// $FlowFixMe[missing-local-annot]
function onRecoverableError(error) {
Expand Down
166 changes: 166 additions & 0 deletions packages/react-native-renderer/src/ReactNativePublicCompat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/**
* 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
*/

import type {HostComponent} from './ReactNativeTypes';
import type {ElementRef, ElementType} from 'react';

// Modules provided by RN:
import {
UIManager,
legacySendAccessibilityEvent,
} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';

import {
findHostInstance,
findHostInstanceWithWarning,
} from 'react-reconciler/src/ReactFiberReconciler';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import getComponentNameFromType from 'shared/getComponentNameFromType';

const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;

export function findHostInstance_DEPRECATED<TElementType: ElementType>(
componentOrHandle: ?(ElementRef<TElementType> | number),
): ?ElementRef<HostComponent<mixed>> {
if (__DEV__) {
const owner = ReactCurrentOwner.current;
if (owner !== null && owner.stateNode !== null) {
if (!owner.stateNode._warnedAboutRefsInRender) {
console.error(
'%s is accessing findNodeHandle inside its render(). ' +
'render() should be a pure function of props and state. It should ' +
'never access something that requires stale data from the previous ' +
'render, such as refs. Move this logic to componentDidMount and ' +
'componentDidUpdate instead.',
getComponentNameFromType(owner.type) || 'A component',
);
}

owner.stateNode._warnedAboutRefsInRender = true;
}
}
if (componentOrHandle == null) {
return null;
}
// $FlowFixMe Flow has hardcoded values for React DOM that don't work with RN
if (componentOrHandle._nativeTag) {
// $FlowFixMe Flow has hardcoded values for React DOM that don't work with RN
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(
componentOrHandle,
'findHostInstance_DEPRECATED',
);
} else {
hostInstance = findHostInstance(componentOrHandle);
}

return hostInstance;
}

export function findNodeHandle(componentOrHandle: any): ?number {
if (__DEV__) {
const owner = ReactCurrentOwner.current;
if (owner !== null && owner.stateNode !== null) {
if (!owner.stateNode._warnedAboutRefsInRender) {
console.error(
'%s is accessing findNodeHandle inside its render(). ' +
'render() should be a pure function of props and state. It should ' +
'never access something that requires stale data from the previous ' +
'render, such as refs. Move this logic to componentDidMount and ' +
'componentDidUpdate instead.',
getComponentNameFromType(owner.type) || 'A component',
);
}

owner.stateNode._warnedAboutRefsInRender = true;
}
}
if (componentOrHandle == null) {
return null;
}
if (typeof componentOrHandle === 'number') {
// Already a node handle
return componentOrHandle;
}
if (componentOrHandle._nativeTag) {
return componentOrHandle._nativeTag;
}
if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) {
return componentOrHandle.canonical._nativeTag;
}
let hostInstance;
if (__DEV__) {
hostInstance = findHostInstanceWithWarning(
componentOrHandle,
'findNodeHandle',
);
} else {
hostInstance = findHostInstance(componentOrHandle);
}

if (hostInstance == null) {
return hostInstance;
}

return hostInstance._nativeTag;
}

export function dispatchCommand(
handle: any,
command: string,
args: Array<any>,
) {
if (handle._nativeTag == null) {
if (__DEV__) {
console.error(
"dispatchCommand was called with a ref that isn't a " +
'native component. Use React.forwardRef to get access to the underlying native component',
);
}
return;
}

if (handle._internalInstanceHandle != null) {
const {stateNode} = handle._internalInstanceHandle;
if (stateNode != null) {
nativeFabricUIManager.dispatchCommand(stateNode.node, command, args);
}
} else {
UIManager.dispatchViewManagerCommand(handle._nativeTag, command, args);
}
}

export function sendAccessibilityEvent(handle: any, eventType: string) {
if (handle._nativeTag == null) {
if (__DEV__) {
console.error(
"sendAccessibilityEvent was called with a ref that isn't a " +
'native component. Use React.forwardRef to get access to the underlying native component',
);
}
return;
}

if (handle._internalInstanceHandle != null) {
const {stateNode} = handle._internalInstanceHandle;
if (stateNode != null) {
nativeFabricUIManager.sendAccessibilityEvent(stateNode.node, eventType);
}
} else {
legacySendAccessibilityEvent(handle._nativeTag, eventType);
}
}
Loading