Skip to content

Commit 9dd378f

Browse files
authored
[RN] Move definition of public instances to ReactNativePrivateInterface (#32446)
## Summary > [!NOTE] > This only modifies types, so shouldn't have an impact at runtime. Some time ago we moved some type definitions from React to React Native in #26437. This continues making progress on that so values that are created by React Native and passed to the React renderer (in this case public instances) are actually defined in React Native and not in React. This will allow us to modify the definition of some of these types without having to make changes in the React repository (in the short term, we want to refactor PublicInstance from an object to an interface, and then modify that interface to add all the new DOM methods). ## How did you test this change? Manually synced `ReactNativeTypes` on top of facebook/react-native#49602 and verified Flow passes.
1 parent ad03c48 commit 9dd378f

File tree

6 files changed

+66
-100
lines changed

6 files changed

+66
-100
lines changed

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@
77
* @flow
88
*/
99

10+
import type {ViewConfig} from './ReactNativeTypes';
1011
import type {
11-
HostInstance,
12+
LegacyPublicInstance,
13+
MeasureOnSuccessCallback,
1214
MeasureInWindowOnSuccessCallback,
1315
MeasureLayoutOnSuccessCallback,
14-
MeasureOnSuccessCallback,
15-
INativeMethods,
16-
ViewConfig,
17-
} from './ReactNativeTypes';
16+
} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
1817
import type {Instance} from './ReactFiberConfigNative';
1918

2019
// Modules provided by RN:
@@ -29,7 +28,7 @@ import {
2928
warnForStyleProps,
3029
} from './NativeMethodsMixinUtils';
3130

32-
class ReactNativeFiberHostComponent implements INativeMethods {
31+
class ReactNativeFiberHostComponent implements LegacyPublicInstance {
3332
_children: Array<Instance | number>;
3433
_nativeTag: number;
3534
_internalFiberInstanceHandleDEV: Object;
@@ -71,7 +70,7 @@ class ReactNativeFiberHostComponent implements INativeMethods {
7170
}
7271

7372
measureLayout(
74-
relativeToNativeNode: number | HostInstance,
73+
relativeToNativeNode: number | LegacyPublicInstance,
7574
onSuccess: MeasureLayoutOnSuccessCallback,
7675
onFail?: () => void /* currently unused */,
7776
) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ function getInspectorDataForViewAtPoint(
236236
pointerY: locationY,
237237
frame: {left, top, width, height},
238238
touchedViewTag: nativeViewTag,
239+
// $FlowExpectedError[incompatible-call]
239240
closestPublicInstance: nativeViewTag,
240241
});
241242
},

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

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
* @flow
88
*/
99

10-
import type {Node, HostComponent} from './ReactNativeTypes';
10+
import type {Node} from './ReactNativeTypes';
1111
import type {ElementRef, ElementType} from 'react';
12+
import type {PublicInstance} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
1213

1314
// Modules provided by RN:
1415
import {
@@ -32,7 +33,7 @@ import {
3233

3334
export function findHostInstance_DEPRECATED<TElementType: ElementType>(
3435
componentOrHandle: ?(ElementRef<TElementType> | number),
35-
): ?ElementRef<HostComponent<{...}>> {
36+
): ?PublicInstance {
3637
if (__DEV__) {
3738
const owner = currentOwner;
3839
if (owner !== null && isRendering && owner.stateNode !== null) {
@@ -222,15 +223,10 @@ export function getNodeFromInternalInstanceHandle(
222223
);
223224
}
224225

225-
// Should have been PublicInstance from ReactFiberConfigFabric
226-
type FabricPublicInstance = mixed;
227-
// Should have been PublicInstance from ReactFiberConfigNative
228-
type PaperPublicInstance = HostComponent<empty>;
229-
230226
// Remove this once Paper is no longer supported and DOM Node API are enabled by default in RN.
231227
export function isChildPublicInstance(
232-
parentInstance: FabricPublicInstance | PaperPublicInstance,
233-
childInstance: FabricPublicInstance | PaperPublicInstance,
228+
parentInstance: PublicInstance,
229+
childInstance: PublicInstance,
234230
): boolean {
235231
if (__DEV__) {
236232
// Paper

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

Lines changed: 17 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,17 @@ import type {
1414
ElementRef,
1515
ElementType,
1616
MixedElement,
17-
RefSetter,
1817
} from 'react';
19-
// $FlowFixMe[nonstrict-import] TODO(@rubennorte)
20-
import {type PublicRootInstance} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
21-
22-
export type MeasureOnSuccessCallback = (
23-
x: number,
24-
y: number,
25-
width: number,
26-
height: number,
27-
pageX: number,
28-
pageY: number,
29-
) => void;
30-
31-
export type MeasureInWindowOnSuccessCallback = (
32-
x: number,
33-
y: number,
34-
width: number,
35-
height: number,
36-
) => void;
37-
38-
export type MeasureLayoutOnSuccessCallback = (
39-
left: number,
40-
top: number,
41-
width: number,
42-
height: number,
43-
) => void;
18+
import type {
19+
// $FlowFixMe[nonstrict-import] TODO(@rubennorte)
20+
MeasureOnSuccessCallback,
21+
// $FlowFixMe[nonstrict-import] TODO(@rubennorte)
22+
PublicInstance,
23+
// $FlowFixMe[nonstrict-import] TODO(@rubennorte)
24+
PublicRootInstance,
25+
// $FlowFixMe[nonstrict-import] TODO(@rubennorte)
26+
PublicTextInstance,
27+
} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
4428

4529
export type AttributeType<T, V> =
4630
| true
@@ -106,45 +90,6 @@ export type PartialViewConfig = $ReadOnly<{
10690
validAttributes?: PartialAttributeConfiguration,
10791
}>;
10892

109-
/**
110-
* Current usages should migrate to this definition
111-
*/
112-
export interface INativeMethods {
113-
blur(): void;
114-
focus(): void;
115-
measure(callback: MeasureOnSuccessCallback): void;
116-
measureInWindow(callback: MeasureInWindowOnSuccessCallback): void;
117-
measureLayout(
118-
relativeToNativeNode: number | HostInstance,
119-
onSuccess: MeasureLayoutOnSuccessCallback,
120-
onFail?: () => void,
121-
): void;
122-
setNativeProps(nativeProps: {...}): void;
123-
}
124-
125-
export type NativeMethods = $ReadOnly<{
126-
blur(): void,
127-
focus(): void,
128-
measure(callback: MeasureOnSuccessCallback): void,
129-
measureInWindow(callback: MeasureInWindowOnSuccessCallback): void,
130-
measureLayout(
131-
relativeToNativeNode: number | HostInstance,
132-
onSuccess: MeasureLayoutOnSuccessCallback,
133-
onFail?: () => void,
134-
): void,
135-
setNativeProps(nativeProps: {...}): void,
136-
}>;
137-
138-
// This validates that INativeMethods and NativeMethods stay in sync using Flow!
139-
declare const ensureNativeMethodsAreSynced: NativeMethods;
140-
(ensureNativeMethodsAreSynced: INativeMethods);
141-
142-
export type HostInstance = NativeMethods;
143-
export type HostComponent<Config: {...}> = component(
144-
ref: RefSetter<HostInstance>,
145-
...Config
146-
);
147-
14893
type InspectorDataProps = $ReadOnly<{
14994
[propName: string]: string,
15095
...
@@ -211,20 +156,17 @@ export type RenderRootOptions = {
211156
export type ReactNativeType = {
212157
findHostInstance_DEPRECATED<TElementType: ElementType>(
213158
componentOrHandle: ?(ElementRef<TElementType> | number),
214-
): ?HostInstance,
159+
): ?PublicInstance,
215160
findNodeHandle<TElementType: ElementType>(
216161
componentOrHandle: ?(ElementRef<TElementType> | number),
217162
): ?number,
218-
isChildPublicInstance(
219-
parent: PublicInstance | HostComponent<empty>,
220-
child: PublicInstance | HostComponent<empty>,
221-
): boolean,
163+
isChildPublicInstance(parent: PublicInstance, child: PublicInstance): boolean,
222164
dispatchCommand(
223-
handle: HostInstance,
165+
handle: PublicInstance,
224166
command: string,
225167
args: Array<mixed>,
226168
): void,
227-
sendAccessibilityEvent(handle: HostInstance, eventType: string): void,
169+
sendAccessibilityEvent(handle: PublicInstance, eventType: string): void,
228170
render(
229171
element: MixedElement,
230172
containerTag: number,
@@ -239,23 +181,21 @@ export type ReactNativeType = {
239181

240182
export opaque type Node = mixed;
241183
export opaque type InternalInstanceHandle = mixed;
242-
type PublicInstance = mixed;
243-
type PublicTextInstance = mixed;
244184

245185
export type ReactFabricType = {
246186
findHostInstance_DEPRECATED<TElementType: ElementType>(
247187
componentOrHandle: ?(ElementRef<TElementType> | number),
248-
): ?HostInstance,
188+
): ?PublicInstance,
249189
findNodeHandle<TElementType: ElementType>(
250190
componentOrHandle: ?(ElementRef<TElementType> | number),
251191
): ?number,
252192
dispatchCommand(
253-
handle: HostInstance,
193+
handle: PublicInstance,
254194
command: string,
255195
args: Array<mixed>,
256196
): void,
257197
isChildPublicInstance(parent: PublicInstance, child: PublicInstance): boolean,
258-
sendAccessibilityEvent(handle: HostInstance, eventType: string): void,
198+
sendAccessibilityEvent(handle: PublicInstance, eventType: string): void,
259199
render(
260200
element: MixedElement,
261201
containerTag: number,

packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/ReactNativePrivateInterface.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@
77
* @flow strict-local
88
*/
99

10-
export opaque type PublicInstance = mixed;
11-
export opaque type PublicTextInstance = mixed;
12-
export opaque type PublicRootInstance = mixed;
13-
1410
module.exports = {
1511
get BatchedBridge() {
1612
return require('./BatchedBridge.js');

scripts/flow/react-native-host-hooks.js

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,26 @@
99

1010
// libdefs cannot actually import. These are supposed to be the types imported
1111
// from 'react-native-renderer/src/ReactNativeTypes'
12-
type __MeasureOnSuccessCallback = any;
13-
type __MeasureInWindowOnSuccessCallback = any;
14-
type __MeasureLayoutOnSuccessCallback = any;
12+
type __MeasureOnSuccessCallback = (
13+
x: number,
14+
y: number,
15+
width: number,
16+
height: number,
17+
pageX: number,
18+
pageY: number,
19+
) => void;
20+
type __MeasureInWindowOnSuccessCallback = (
21+
x: number,
22+
y: number,
23+
width: number,
24+
height: number,
25+
) => void;
26+
type __MeasureLayoutOnSuccessCallback = (
27+
left: number,
28+
top: number,
29+
width: number,
30+
height: number,
31+
) => void;
1532
type __ReactNativeBaseComponentViewConfig = any;
1633
type __ViewConfigGetter = any;
1734
type __ViewConfig = any;
@@ -144,6 +161,23 @@ declare module 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'
144161
declare export opaque type PublicInstance;
145162
declare export opaque type PublicTextInstance;
146163
declare export opaque type PublicRootInstance;
164+
declare export type MeasureOnSuccessCallback = __MeasureOnSuccessCallback;
165+
declare export type MeasureInWindowOnSuccessCallback =
166+
__MeasureInWindowOnSuccessCallback;
167+
declare export type MeasureLayoutOnSuccessCallback =
168+
__MeasureLayoutOnSuccessCallback;
169+
declare export interface LegacyPublicInstance {
170+
blur(): void;
171+
focus(): void;
172+
measure(callback: __MeasureOnSuccessCallback): void;
173+
measureInWindow(callback: __MeasureInWindowOnSuccessCallback): void;
174+
measureLayout(
175+
relativeToNativeNode: number | LegacyPublicInstance,
176+
onSuccess: __MeasureLayoutOnSuccessCallback,
177+
onFail?: () => void,
178+
): void;
179+
setNativeProps(nativeProps: {...}): void;
180+
}
147181
declare export function getNodeFromPublicInstance(
148182
publicInstance: PublicInstance,
149183
): Object;

0 commit comments

Comments
 (0)