Skip to content

Commit

Permalink
Extracted definition and access to public instances to a separate mod…
Browse files Browse the repository at this point in the history
…ule in Fabric
  • Loading branch information
rubennorte committed Mar 3, 2023
1 parent 4bb596b commit 02238bc
Show file tree
Hide file tree
Showing 11 changed files with 318 additions and 198 deletions.
44 changes: 33 additions & 11 deletions packages/react-native-renderer/src/ReactFabric.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
import {createPortal as createPortalImpl} from 'react-reconciler/src/ReactPortal';
import {setBatchingImplementation} from './legacy-events/ReactGenericBatching';
import ReactVersion from 'shared/ReactVersion';
import {getNativeTagFromPublicInstance} from './ReactFabricPublicInstanceUtils';

// Modules provided by RN:
import {
Expand All @@ -44,6 +45,7 @@ import {
import {LegacyRoot, ConcurrentRoot} from 'react-reconciler/src/ReactRootTags';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import getComponentNameFromType from 'shared/getComponentNameFromType';
import type {PublicInstance} from './ReactFabricHostConfig';

const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;

Expand All @@ -67,19 +69,23 @@ function findHostInstance_DEPRECATED<TElementType: ElementType>(
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;

// For compatibility with Paper
if (componentOrHandle._nativeTag != null) {
// $FlowExpectedError[incompatible-cast] we assume it's a Paper instance if it has a `_nativeTag` property.
return (componentOrHandle: PublicInstance);
}
// $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;

// Fabric-specific
if (componentOrHandle.publicInstance != null) {
// $FlowExpectedError[incompatible-cast] we assume it's a Fabric instance if it has a `publicInstance` field.
return (componentOrHandle.publicInstance: PublicInstance);
}

let hostInstance;
if (__DEV__) {
hostInstance = findHostInstanceWithWarning(
Expand Down Expand Up @@ -111,19 +117,28 @@ 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 Paper
if (componentOrHandle._nativeTag) {
return componentOrHandle._nativeTag;
}
if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) {
return componentOrHandle.canonical._nativeTag;

if (componentOrHandle.internals != null) {
const nativeTag = componentOrHandle.internals.nativeTag;
if (nativeTag != null) {
return nativeTag;
}
}

let hostInstance;
if (__DEV__) {
hostInstance = findHostInstanceWithWarning(
Expand All @@ -138,7 +153,13 @@ function findNodeHandle(componentOrHandle: any): ?number {
return hostInstance;
}

return hostInstance._nativeTag;
// For compatibility with Paper
if (hostInstance._nativeTag != null) {
return hostInstance._nativeTag;
}

// $FlowExpectedError[incompatible-call] this fails for the definition of `Instance` in Paper, but here it's always a Fabric instance.
return getNativeTagFromPublicInstance(hostInstance);
}

function dispatchCommand(handle: any, command: string, args: Array<any>) {
Expand Down Expand Up @@ -265,6 +286,7 @@ export {
};

injectIntoDevTools({
// $FlowExpectedError[incompatible-call] The type of `Instance` in `getClosestInstanceFromNode` does not match in Fabric and Paper, so it fails to typecheck here.
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: __DEV__ ? 1 : 0,
version: ReactVersion,
Expand Down
53 changes: 39 additions & 14 deletions packages/react-native-renderer/src/ReactFabricComponentTree.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,53 @@
*
* 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
*/

function getInstanceFromInstance(instanceHandle) {
return instanceHandle;
import type {
PublicInstance,
Instance,
Props,
TextInstance,
} from './ReactFabricHostConfig';
import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
import {getPublicInstance} from './ReactFabricHostConfig';

// `node` is typed incorrectly here. The proper type should be `PublicInstance`.
// 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;
}

function getTagFromInstance(inst) {
const nativeInstance = inst.stateNode.canonical;
function getNodeFromInstance(fiber: Fiber): PublicInstance {
const publicInstance = getPublicInstance(fiber.stateNode);

if (!nativeInstance._nativeTag) {
throw new Error('All native instances should have a tag.');
if (publicInstance == null) {
throw new Error('Could not find host instance from fiber');
}

return nativeInstance;
return publicInstance;
}

function getFiberCurrentPropsFromNode(instance: Instance): Props {
return instance && instance.internals && instance.internals.currentProps;
}

export {
getInstanceFromInstance as getClosestInstanceFromNode,
getInstanceFromInstance as getInstanceFromNode,
getTagFromInstance as getNodeFromInstance,
getInstanceFromNode,
getInstanceFromNode as getClosestInstanceFromNode,
getNodeFromInstance,
getFiberCurrentPropsFromNode,
};

export function getFiberCurrentPropsFromNode(inst) {
return inst.canonical.currentProps;
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
import {batchedUpdates} from './legacy-events/ReactGenericBatching';
import accumulateInto from './legacy-events/accumulateInto';

import {getPublicInstance} from './ReactFabricHostConfig';
import getListener from './ReactNativeGetListener';
import {runEventsInBatch} from './legacy-events/EventBatching';

Expand Down Expand Up @@ -92,7 +93,8 @@ export function dispatchEvent(
const stateNode = targetFiber.stateNode;
// Guard against Fiber being unmounted
if (stateNode != null) {
eventTarget = stateNode.canonical;
// $FlowExpectedError[incompatible-cast] public instances in Fabric do not implement `EventTarget` yet.
eventTarget = (getPublicInstance(stateNode): EventTarget);
}
}

Expand Down
Loading

0 comments on commit 02238bc

Please sign in to comment.