Skip to content

Commit 5887cde

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

12 files changed

+343
-218
lines changed

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

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -45,26 +45,6 @@ export function mountSafeCallback_NOT_REALLY_SAFE(
4545
};
4646
}
4747

48-
export function throwOnStylesProp(component: any, props: any) {
49-
if (props.styles !== undefined) {
50-
const owner = component._owner || null;
51-
const name = component.constructor.displayName;
52-
let msg =
53-
'`styles` is not a supported property of `' +
54-
name +
55-
'`, did ' +
56-
'you mean `style` (singular)?';
57-
if (owner && owner.constructor && owner.constructor.displayName) {
58-
msg +=
59-
'\n\nCheck the `' +
60-
owner.constructor.displayName +
61-
'` parent ' +
62-
' component.';
63-
}
64-
throw new Error(msg);
65-
}
66-
}
67-
6848
export function warnForStyleProps(props: any, validAttributes: any) {
6949
if (__DEV__) {
7050
for (const key in validAttributes.style) {

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

Lines changed: 34 additions & 11 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 {
@@ -44,6 +45,7 @@ import {
4445
import {LegacyRoot, ConcurrentRoot} from 'react-reconciler/src/ReactRootTags';
4546
import ReactSharedInternals from 'shared/ReactSharedInternals';
4647
import getComponentNameFromType from 'shared/getComponentNameFromType';
48+
import type {PublicInstance} from './ReactFabricHostConfig';
4749

4850
const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
4951

@@ -67,19 +69,23 @@ function findHostInstance_DEPRECATED<TElementType: ElementType>(
6769
owner.stateNode._warnedAboutRefsInRender = true;
6870
}
6971
}
72+
7073
if (componentOrHandle == null) {
7174
return null;
7275
}
73-
// $FlowFixMe Flow has hardcoded values for React DOM that don't work with RN
74-
if (componentOrHandle._nativeTag) {
75-
// $FlowFixMe Flow has hardcoded values for React DOM that don't work with RN
76-
return componentOrHandle;
76+
77+
// For compatibility with Paper
78+
if (componentOrHandle._nativeTag != null) {
79+
// $FlowExpectedError[incompatible-cast] For compatibility with Paper (when using Fabric)
80+
return (componentOrHandle: PublicInstance);
7781
}
78-
// $FlowFixMe Flow has hardcoded values for React DOM that don't work with RN
79-
if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) {
80-
// $FlowFixMe Flow has hardcoded values for React DOM that don't work with RN
81-
return componentOrHandle.canonical;
82+
83+
// Fabric-specific
84+
if (componentOrHandle.publicInstance != null) {
85+
// $FlowExpectedError[incompatible-cast] For compatibility with Fabric (when using Paper)
86+
return (componentOrHandle.publicInstance: PublicInstance);
8287
}
88+
8389
let hostInstance;
8490
if (__DEV__) {
8591
hostInstance = findHostInstanceWithWarning(
@@ -111,19 +117,28 @@ function findNodeHandle(componentOrHandle: any): ?number {
111117
owner.stateNode._warnedAboutRefsInRender = true;
112118
}
113119
}
120+
114121
if (componentOrHandle == null) {
115122
return null;
116123
}
124+
117125
if (typeof componentOrHandle === 'number') {
118126
// Already a node handle
119127
return componentOrHandle;
120128
}
129+
130+
// For compatibility with Paper
121131
if (componentOrHandle._nativeTag) {
122132
return componentOrHandle._nativeTag;
123133
}
124-
if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) {
125-
return componentOrHandle.canonical._nativeTag;
134+
135+
if (componentOrHandle.internals != null) {
136+
const nativeTag = componentOrHandle.internals.nativeTag;
137+
if (nativeTag != null) {
138+
return nativeTag;
139+
}
126140
}
141+
127142
let hostInstance;
128143
if (__DEV__) {
129144
hostInstance = findHostInstanceWithWarning(
@@ -138,7 +153,14 @@ function findNodeHandle(componentOrHandle: any): ?number {
138153
return hostInstance;
139154
}
140155

141-
return hostInstance._nativeTag;
156+
// $FlowExpectedError[prop-missing] For compatibility with Paper (when using Fabric)
157+
if (hostInstance._nativeTag != null) {
158+
// $FlowExpectedError[incompatible-return]
159+
return hostInstance._nativeTag;
160+
}
161+
162+
// $FlowExpectedError[incompatible-call] For compatibility with Fabric (when using Paper)
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)