Skip to content

Commit 752e093

Browse files
committed
Extracted definition and access to public instances to a separate module in Fabric
1 parent 4bb596b commit 752e093

11 files changed

+290
-188
lines changed

packages/react-native-renderer/src/ReactFabric.js

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
import {createPortal as createPortalImpl} from 'react-reconciler/src/ReactPortal';
2929
import {setBatchingImplementation} from './legacy-events/ReactGenericBatching';
3030
import ReactVersion from 'shared/ReactVersion';
31+
import {getNativeTagFromPublicInstance} from './ReactFabricPublicInstanceUtils';
3132

3233
// Modules provided by RN:
3334
import {
@@ -67,19 +68,25 @@ function findHostInstance_DEPRECATED<TElementType: ElementType>(
6768
owner.stateNode._warnedAboutRefsInRender = true;
6869
}
6970
}
71+
7072
if (componentOrHandle == null) {
7173
return null;
7274
}
75+
76+
// For compatibility with Paper
7377
// $FlowFixMe Flow has hardcoded values for React DOM that don't work with RN
74-
if (componentOrHandle._nativeTag) {
78+
if (componentOrHandle._nativeTag != null) {
7579
// $FlowFixMe Flow has hardcoded values for React DOM that don't work with RN
7680
return componentOrHandle;
7781
}
82+
83+
// Fabric-specific
7884
// $FlowFixMe Flow has hardcoded values for React DOM that don't work with RN
79-
if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) {
85+
if (componentOrHandle.publicInstance != null) {
8086
// $FlowFixMe Flow has hardcoded values for React DOM that don't work with RN
81-
return componentOrHandle.canonical;
87+
return componentOrHandle.publicInstance;
8288
}
89+
8390
let hostInstance;
8491
if (__DEV__) {
8592
hostInstance = findHostInstanceWithWarning(
@@ -111,19 +118,28 @@ function findNodeHandle(componentOrHandle: any): ?number {
111118
owner.stateNode._warnedAboutRefsInRender = true;
112119
}
113120
}
121+
114122
if (componentOrHandle == null) {
115123
return null;
116124
}
125+
117126
if (typeof componentOrHandle === 'number') {
118127
// Already a node handle
119128
return componentOrHandle;
120129
}
130+
131+
// For compatibility with Paper
121132
if (componentOrHandle._nativeTag) {
122133
return componentOrHandle._nativeTag;
123134
}
124-
if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) {
125-
return componentOrHandle.canonical._nativeTag;
135+
136+
if (componentOrHandle.internals != null) {
137+
const nativeTag = componentOrHandle.internals.nativeTag;
138+
if (nativeTag != null) {
139+
return nativeTag;
140+
}
126141
}
142+
127143
let hostInstance;
128144
if (__DEV__) {
129145
hostInstance = findHostInstanceWithWarning(
@@ -138,7 +154,13 @@ function findNodeHandle(componentOrHandle: any): ?number {
138154
return hostInstance;
139155
}
140156

141-
return hostInstance._nativeTag;
157+
// For compatibility with Paper
158+
if (hostInstance._nativeTag != null) {
159+
return hostInstance._nativeTag;
160+
}
161+
162+
// $FlowExpectedError[incompatible-call] this fails for the definition of `Instance` in Paper, but here it's always a Fabric instance.
163+
return getNativeTagFromPublicInstance(hostInstance);
142164
}
143165

144166
function dispatchCommand(handle: any, command: string, args: Array<any>) {
@@ -265,6 +287,7 @@ export {
265287
};
266288

267289
injectIntoDevTools({
290+
// $FlowExpectedError[incompatible-call] The type of `Instance` in `getClosestInstanceFromNode` does not match in Fabric and Paper, so it fails to typecheck here.
268291
findFiberByHostInstance: getClosestInstanceFromNode,
269292
bundleType: __DEV__ ? 1 : 0,
270293
version: ReactVersion,

packages/react-native-renderer/src/ReactFabricComponentTree.js

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,53 @@
33
*
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict-local
68
*/
79

8-
function getInstanceFromInstance(instanceHandle) {
9-
return instanceHandle;
10+
import type {
11+
PublicInstance,
12+
Instance,
13+
Props,
14+
TextInstance,
15+
} from './ReactFabricHostConfig';
16+
import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
17+
import {getPublicInstance} from './ReactFabricHostConfig';
18+
19+
// `node` is typed incorrectly here. The proper type should be `PublicInstance`.
20+
// This is ok in DOM because they types are interchangeable, but in React Native
21+
// they aren't.
22+
function getInstanceFromNode(node: Instance | TextInstance): Fiber | null {
23+
const instance: Instance = (node: $FlowFixMe); // In React Native, node is never a text instance
24+
25+
if (
26+
instance.internals != null &&
27+
instance.internals.internalInstanceHandle != null
28+
) {
29+
return instance.internals.internalInstanceHandle;
30+
}
31+
32+
// $FlowFixMe[incompatible-return] DevTools incorrectly passes a fiber in React Native.
33+
return node;
1034
}
1135

12-
function getTagFromInstance(inst) {
13-
const nativeInstance = inst.stateNode.canonical;
36+
function getNodeFromInstance(fiber: Fiber): PublicInstance {
37+
const publicInstance = getPublicInstance(fiber.stateNode);
1438

15-
if (!nativeInstance._nativeTag) {
16-
throw new Error('All native instances should have a tag.');
39+
if (publicInstance == null) {
40+
throw new Error('Could not find host instance from fiber');
1741
}
1842

19-
return nativeInstance;
43+
return publicInstance;
44+
}
45+
46+
function getFiberCurrentPropsFromNode(instance: Instance): Props {
47+
return instance && instance.internals && instance.internals.currentProps;
2048
}
2149

2250
export {
23-
getInstanceFromInstance as getClosestInstanceFromNode,
24-
getInstanceFromInstance as getInstanceFromNode,
25-
getTagFromInstance as getNodeFromInstance,
51+
getInstanceFromNode,
52+
getInstanceFromNode as getClosestInstanceFromNode,
53+
getNodeFromInstance,
54+
getFiberCurrentPropsFromNode,
2655
};
27-
28-
export function getFiberCurrentPropsFromNode(inst) {
29-
return inst.canonical.currentProps;
30-
}

packages/react-native-renderer/src/ReactFabricEventEmitter.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
import {batchedUpdates} from './legacy-events/ReactGenericBatching';
2626
import accumulateInto from './legacy-events/accumulateInto';
2727

28+
import {getPublicInstance} from './ReactFabricHostConfig';
2829
import getListener from './ReactNativeGetListener';
2930
import {runEventsInBatch} from './legacy-events/EventBatching';
3031

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

0 commit comments

Comments
 (0)