Remove ReactFabricPublicInstance and used definition from ReactNativePrivateInterface (#26437)
## Summary Now that React Native owns the definition for public instances in Fabric and ReactNativePrivateInterface provides the methods to create instances and access private fields (see https://github.com/facebook/react-native/pull/36570), we can remove the definitions from React. After this PR, React Native public instances will be opaque types for React and it will only handle their creation but not their definition. This will make RN similar to DOM in how public instances are handled. This is a new version of #26418 which was closed without merging. ## How did you test this change? * Existing tests. * Manually synced the changes in this PR to React Native and tested it end to end in Meta's infra.
Rubén Norte committed
Mar 22, 2023 at 17:54 UTC
9c54b29b44d24f8f8090da9c7ebf569747a444df
13 files changed
+96
-455
packages/react-native-renderer/src/ReactFabricHostConfig.js
+4
-6
@@ -8,10 +8,6 @@
8
*/
9
10
import type {TouchedViewDataAtPoint, ViewConfig} from './ReactNativeTypes';
11
-import {
12
- createPublicInstance,
13
- type ReactFabricHostComponent,
14
-} from './ReactFabricPublicInstance';
11
import {create, diff} from './ReactNativeAttributePayload';
12
import {dispatchEvent} from './ReactFabricEventEmitter';
13
import {
@@ -23,6 +19,8 @@ import {
19
import {
20
ReactNativeViewConfigRegistry,
21
deepFreezeAndThrowOnMutationInDev,
22
+ createPublicInstance,
23
+ type PublicInstance as ReactNativePublicInstance,
24
} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
25
26
const {
@@ -62,12 +60,12 @@ export type Instance = {
60
// Reference to the React handle (the fiber)
61
internalInstanceHandle: Object,
62
// Exposed through refs.
65
- publicInstance: ReactFabricHostComponent,
63
+ publicInstance: PublicInstance,
64
},
65
};
66
export type TextInstance = {node: Node, ...};
67
export type HydratableInstance = Instance | TextInstance;
70
-export type PublicInstance = ReactFabricHostComponent;
68
+export type PublicInstance = ReactNativePublicInstance;
69
export type Container = number;
70
export type ChildSet = Object;
71
export type HostContext = $ReadOnly<{
packages/react-native-renderer/src/ReactFabricPublicInstance.js
deleted
-153
@@ -1,153 +0,0 @@
1
-/**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow strict-local
8
- */
9
-
10
-import type {ElementRef} from 'react';
11
-import type {
12
- ViewConfig,
13
- INativeMethods,
14
- HostComponent,
15
- MeasureInWindowOnSuccessCallback,
16
- MeasureLayoutOnSuccessCallback,
17
- MeasureOnSuccessCallback,
18
-} from './ReactNativeTypes';
19
-
20
-import {TextInputState} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
21
-import {create} from './ReactNativeAttributePayload';
22
-import {warnForStyleProps} from './NativeMethodsMixinUtils';
23
-import {getNodeFromInternalInstanceHandle} from './ReactNativePublicCompat';
24
-
25
-const {
26
- measure: fabricMeasure,
27
- measureInWindow: fabricMeasureInWindow,
28
- measureLayout: fabricMeasureLayout,
29
- setNativeProps,
30
- getBoundingClientRect: fabricGetBoundingClientRect,
31
-} = nativeFabricUIManager;
32
-
33
-const noop = () => {};
34
-
35
-/**
36
- * This is used for refs on host components.
37
- */
38
-export class ReactFabricHostComponent implements INativeMethods {
39
- // These need to be accessible from `ReactFabricPublicInstanceUtils`.
40
- __nativeTag: number;
41
- __internalInstanceHandle: mixed;
42
-
43
- _viewConfig: ViewConfig;
44
-
45
- constructor(
46
- tag: number,
47
- viewConfig: ViewConfig,
48
- internalInstanceHandle: mixed,
49
- ) {
50
- this.__nativeTag = tag;
51
- this._viewConfig = viewConfig;
52
- this.__internalInstanceHandle = internalInstanceHandle;
53
- }
54
-
55
- blur() {
56
- TextInputState.blurTextInput(this);
57
- }
58
-
59
- focus() {
60
- TextInputState.focusTextInput(this);
61
- }
62
-
63
- measure(callback: MeasureOnSuccessCallback) {
64
- const node = getNodeFromInternalInstanceHandle(
65
- this.__internalInstanceHandle,
66
- );
67
- if (node != null) {
68
- fabricMeasure(node, callback);
69
- }
70
- }
71
-
72
- measureInWindow(callback: MeasureInWindowOnSuccessCallback) {
73
- const node = getNodeFromInternalInstanceHandle(
74
- this.__internalInstanceHandle,
75
- );
76
- if (node != null) {
77
- fabricMeasureInWindow(node, callback);
78
- }
79
- }
80
-
81
- measureLayout(
82
- relativeToNativeNode: number | ElementRef<HostComponent<mixed>>,
83
- onSuccess: MeasureLayoutOnSuccessCallback,
84
- onFail?: () => void /* currently unused */,
85
- ) {
86
- if (
87
- typeof relativeToNativeNode === 'number' ||
88
- !(relativeToNativeNode instanceof ReactFabricHostComponent)
89
- ) {
90
- if (__DEV__) {
91
- console.error(
92
- 'Warning: ref.measureLayout must be called with a ref to a native component.',
93
- );
94
- }
95
-
96
- return;
97
- }
98
-
99
- const toStateNode = getNodeFromInternalInstanceHandle(
100
- this.__internalInstanceHandle,
101
- );
102
- const fromStateNode = getNodeFromInternalInstanceHandle(
103
- relativeToNativeNode.__internalInstanceHandle,
104
- );
105
-
106
- if (toStateNode != null && fromStateNode != null) {
107
- fabricMeasureLayout(
108
- toStateNode,
109
- fromStateNode,
110
- onFail != null ? onFail : noop,
111
- onSuccess != null ? onSuccess : noop,
112
- );
113
- }
114
- }
115
-
116
- unstable_getBoundingClientRect(): DOMRect {
117
- const node = getNodeFromInternalInstanceHandle(
118
- this.__internalInstanceHandle,
119
- );
120
- if (node != null) {
121
- const rect = fabricGetBoundingClientRect(node);
122
-
123
- if (rect) {
124
- return new DOMRect(rect[0], rect[1], rect[2], rect[3]);
125
- }
126
- }
127
-
128
- // Empty rect if any of the above failed
129
- return new DOMRect(0, 0, 0, 0);
130
- }
131
-
132
- setNativeProps(nativeProps: {...}): void {
133
- if (__DEV__) {
134
- warnForStyleProps(nativeProps, this._viewConfig.validAttributes);
135
- }
136
- const updatePayload = create(nativeProps, this._viewConfig.validAttributes);
137
-
138
- const node = getNodeFromInternalInstanceHandle(
139
- this.__internalInstanceHandle,
140
- );
141
- if (node != null && updatePayload != null) {
142
- setNativeProps(node, updatePayload);
143
- }
144
- }
145
-}
146
-
147
-export function createPublicInstance(
148
- tag: number,
149
- viewConfig: ViewConfig,
150
- internalInstanceHandle: mixed,
151
-): ReactFabricHostComponent {
152
- return new ReactFabricHostComponent(tag, viewConfig, internalInstanceHandle);
153
-}
packages/react-native-renderer/src/ReactFabricPublicInstanceUtils.js
deleted
-36
@@ -1,36 +0,0 @@
1
-/**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow strict-local
8
- */
9
-
10
-import type {ReactFabricHostComponent} from './ReactFabricPublicInstance';
11
-import {getNodeFromInternalInstanceHandle} from './ReactNativePublicCompat';
12
-
13
-/**
14
- * IMPORTANT: This module is used in Paper and Fabric. It needs to be defined
15
- * outside of `ReactFabricPublicInstance` because that module requires
16
- * `nativeFabricUIManager` to be defined in the global scope (which does not
17
- * happen in Paper).
18
- */
19
-
20
-export function getNativeTagFromPublicInstance(
21
- publicInstance: ReactFabricHostComponent,
22
-): number {
23
- return publicInstance.__nativeTag;
24
-}
25
-
26
-export function getNodeFromPublicInstance(
27
- publicInstance: ReactFabricHostComponent,
28
-): mixed {
29
- if (publicInstance.__internalInstanceHandle == null) {
30
- return null;
31
- }
32
-
33
- return getNodeFromInternalInstanceHandle(
34
- publicInstance.__internalInstanceHandle,
35
- );
36
-}
packages/react-native-renderer/src/ReactNativeFiberInspector.js
+4
-2
@@ -17,10 +17,12 @@ import {
17
import getComponentNameFromType from 'shared/getComponentNameFromType';
18
import {HostComponent} from 'react-reconciler/src/ReactWorkTags';
19
// Module provided by RN:
20
-import {UIManager} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
20
+import {
21
+ UIManager,
22
+ getNodeFromPublicInstance,
23
+} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
24
import {enableGetInspectorDataForInstanceInProduction} from 'shared/ReactFeatureFlags';
25
import {getClosestInstanceFromNode} from './ReactNativeComponentTree';
23
-import {getNodeFromPublicInstance} from './ReactFabricPublicInstanceUtils';
26
import {getNodeFromInternalInstanceHandle} from './ReactNativePublicCompat';
27
28
const emptyObject = {};
packages/react-native-renderer/src/ReactNativePublicCompat.js
+4
-7
@@ -14,6 +14,8 @@ import type {ElementRef, ElementType} from 'react';
14
import {
15
UIManager,
16
legacySendAccessibilityEvent,
17
+ getNodeFromPublicInstance,
18
+ getNativeTagFromPublicInstance,
19
} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
20
21
import {
@@ -23,11 +25,6 @@ import {
25
import ReactSharedInternals from 'shared/ReactSharedInternals';
26
import getComponentNameFromType from 'shared/getComponentNameFromType';
27
26
-import {
27
- getNodeFromPublicInstance,
28
- getNativeTagFromPublicInstance,
29
-} from './ReactFabricPublicInstanceUtils';
30
-
28
const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
29
30
export function findHostInstance_DEPRECATED<TElementType: ElementType>(
@@ -83,6 +80,7 @@ export function findHostInstance_DEPRECATED<TElementType: ElementType>(
80
81
// findHostInstance handles legacy vs. Fabric differences correctly
82
// $FlowFixMe[incompatible-exact] we need to fix the definition of `HostComponent` to use NativeMethods as an interface, not as a type.
83
+ // $FlowFixMe[incompatible-return]
84
return hostInstance;
85
}
86
@@ -147,9 +145,8 @@ export function findNodeHandle(componentOrHandle: any): ?number {
145
return hostInstance;
146
}
147
150
- // $FlowFixMe[prop-missing] For compatibility with legacy renderer instances
148
+ // $FlowFixMe[incompatible-type] For compatibility with legacy renderer instances
149
if (hostInstance._nativeTag != null) {
152
- // $FlowFixMe[incompatible-return]
150
return hostInstance._nativeTag;
151
}
152
packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/ReactNativePrivateInterface.js
+11
@@ -7,6 +7,8 @@
7
* @flow strict-local
8
*/
9
10
+export opaque type PublicInstance = mixed;
11
+
12
module.exports = {
13
get BatchedBridge() {
14
return require('./BatchedBridge.js');
@@ -44,4 +46,13 @@ module.exports = {
46
get RawEventEmitter() {
47
return require('./RawEventEmitter').default;
48
},
49
+ get getNativeTagFromPublicInstance() {
50
+ return require('./getNativeTagFromPublicInstance').default;
51
+ },
52
+ get getNodeFromPublicInstance() {
53
+ return require('./getNodeFromPublicInstance').default;
54
+ },
55
+ get createPublicInstance() {
56
+ return require('./createPublicInstance').default;
57
+ },
58
};
packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/createPublicInstance.js
new
+21
@@ -0,0 +1,21 @@
1
+/**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow strict
8
+ */
9
+
10
+import type {PublicInstance} from './ReactNativePrivateInterface';
11
+
12
+export default function createPublicInstance(
13
+ tag: number,
14
+ viewConfig: mixed,
15
+ internalInstanceHandle: mixed,
16
+): PublicInstance {
17
+ return {
18
+ __nativeTag: tag,
19
+ __internalInstanceHandle: internalInstanceHandle,
20
+ };
21
+}
packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/getNativeTagFromPublicInstance.js
new
+16
@@ -0,0 +1,16 @@
1
+/**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow strict
8
+ */
9
+
10
+import type {PublicInstance} from './ReactNativePrivateInterface';
11
+
12
+export default function getNativeTagFromPublicInstance(
13
+ publicInstance: PublicInstance,
14
+) {
15
+ return publicInstance.__nativeTag;
16
+}
packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/getNodeFromPublicInstance.js
new
+20
@@ -0,0 +1,20 @@
1
+/**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow strict
8
+ */
9
+
10
+import type {PublicInstance} from './ReactNativePrivateInterface';
11
+
12
+import {getNodeFromInternalInstanceHandle} from '../../../../ReactNativePublicCompat';
13
+
14
+export default function getNodeFromPublicInstance(
15
+ publicInstance: PublicInstance,
16
+) {
17
+ return getNodeFromInternalInstanceHandle(
18
+ publicInstance.__internalInstanceHandle,
19
+ );
20
+}
packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js
+2
-2
@@ -43,9 +43,9 @@ describe('ReactFabric', () => {
43
require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface')
44
.ReactNativeViewConfigRegistry.register;
45
getNativeTagFromPublicInstance =
46
- require('../ReactFabricPublicInstanceUtils').getNativeTagFromPublicInstance;
46
+ require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface').getNativeTagFromPublicInstance;
47
getNodeFromPublicInstance =
48
- require('../ReactFabricPublicInstanceUtils').getNodeFromPublicInstance;
48
+ require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface').getNodeFromPublicInstance;
49
50
act = require('internal-test-utils').act;
51
});
packages/react-native-renderer/src/__tests__/ReactFabricAndNative-test.internal.js
+1
-1
@@ -37,7 +37,7 @@ describe('created with ReactFabric called with ReactNative', () => {
37
require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface')
38
.ReactNativeViewConfigRegistry.register;
39
getNativeTagFromPublicInstance =
40
- require('../ReactFabricPublicInstanceUtils').getNativeTagFromPublicInstance;
40
+ require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface').getNativeTagFromPublicInstance;
41
});
42
43
it('find Fabric instances with the RN renderer', () => {
packages/react-native-renderer/src/__tests__/ReactFabricHostComponent-test.internal.js
deleted
-248
@@ -1,248 +0,0 @@
1
-/**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * @emails react-core
5
- * @jest-environment node
6
- */
7
-
8
-'use strict';
9
-
10
-import * as React from 'react';
11
-
12
-beforeEach(() => {
13
- jest.resetModules();
14
- jest.restoreAllMocks();
15
-
16
- require('react-native/Libraries/ReactPrivate/InitializeNativeFabricUIManager');
17
-});
18
-
19
-/**
20
- * Renders a sequence of mock views as dictated by `keyLists`. The `keyLists`
21
- * argument is an array of arrays which determines the number of render passes,
22
- * how many views will be rendered in each pass, and what the keys are for each
23
- * of the views.
24
- *
25
- * If an element in `keyLists` is null, the entire root will be unmounted.
26
- *
27
- * The return value is an array of arrays with the resulting refs from rendering
28
- * each corresponding array of keys.
29
- *
30
- * If the corresponding array of keys is null, the returned element at that
31
- * index will also be null.
32
- */
33
-async function mockRenderKeys(keyLists) {
34
- const ReactFabric = require('react-native-renderer/fabric');
35
- const createReactNativeComponentClass =
36
- require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface')
37
- .ReactNativeViewConfigRegistry.register;
38
- const act = require('internal-test-utils').act;
39
-
40
- const mockContainerTag = 11;
41
- const MockView = createReactNativeComponentClass('RCTMockView', () => ({
42
- validAttributes: {foo: true},
43
- uiViewClassName: 'RCTMockView',
44
- }));
45
-
46
- const result = [];
47
- for (let i = 0; i < keyLists.length; i++) {
48
- const keyList = keyLists[i];
49
- if (Array.isArray(keyList)) {
50
- const refs = keyList.map(key => undefined);
51
- await act(() => {
52
- ReactFabric.render(
53
- <MockView>
54
- {keyList.map((key, index) => (
55
- <MockView
56
- key={key}
57
- ref={ref => {
58
- refs[index] = ref;
59
- }}
60
- />
61
- ))}
62
- </MockView>,
63
- mockContainerTag,
64
- );
65
- });
66
- // Clone `refs` to ignore future passes.
67
- result.push([...refs]);
68
- continue;
69
- }
70
- if (keyList == null) {
71
- await act(() => {
72
- ReactFabric.stopSurface(mockContainerTag);
73
- });
74
- result.push(null);
75
- continue;
76
- }
77
- throw new TypeError(
78
- `Invalid 'keyLists' element of type ${typeof keyList}.`,
79
- );
80
- }
81
-
82
- return result;
83
-}
84
-
85
-describe('blur', () => {
86
- test('blur() invokes TextInputState', async () => {
87
- const {
88
- TextInputState,
89
- } = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface');
90
-
91
- const [[fooRef]] = await mockRenderKeys([['foo']]);
92
-
93
- fooRef.blur();
94
-
95
- expect(TextInputState.blurTextInput.mock.calls).toEqual([[fooRef]]);
96
- });
97
-});
98
-
99
-describe('focus', () => {
100
- test('focus() invokes TextInputState', async () => {
101
- const {
102
- TextInputState,
103
- } = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface');
104
-
105
- const [[fooRef]] = await mockRenderKeys([['foo']]);
106
-
107
- fooRef.focus();
108
-
109
- expect(TextInputState.focusTextInput.mock.calls).toEqual([[fooRef]]);
110
- });
111
-});
112
-
113
-describe('measure', () => {
114
- test('component.measure(...) invokes callback', async () => {
115
- const [[fooRef]] = await mockRenderKeys([['foo']]);
116
-
117
- const callback = jest.fn();
118
- fooRef.measure(callback);
119
-
120
- expect(nativeFabricUIManager.measure).toHaveBeenCalledTimes(1);
121
- expect(callback.mock.calls).toEqual([[10, 10, 100, 100, 0, 0]]);
122
- });
123
-
124
- test('unmounted.measure(...) does nothing', async () => {
125
- const [[fooRef]] = await mockRenderKeys([['foo'], null]);
126
-
127
- const callback = jest.fn();
128
- fooRef.measure(callback);
129
-
130
- expect(nativeFabricUIManager.measure).not.toHaveBeenCalled();
131
- expect(callback).not.toHaveBeenCalled();
132
- });
133
-});
134
-
135
-describe('measureInWindow', () => {
136
- test('component.measureInWindow(...) invokes callback', async () => {
137
- const [[fooRef]] = await mockRenderKeys([['foo']]);
138
-
139
- const callback = jest.fn();
140
- fooRef.measureInWindow(callback);
141
-
142
- expect(nativeFabricUIManager.measureInWindow).toHaveBeenCalledTimes(1);
143
- expect(callback.mock.calls).toEqual([[10, 10, 100, 100]]);
144
- });
145
-
146
- test('unmounted.measureInWindow(...) does nothing', async () => {
147
- const [[fooRef]] = await mockRenderKeys([['foo'], null]);
148
-
149
- const callback = jest.fn();
150
- fooRef.measureInWindow(callback);
151
-
152
- expect(nativeFabricUIManager.measureInWindow).not.toHaveBeenCalled();
153
- expect(callback).not.toHaveBeenCalled();
154
- });
155
-});
156
-
157
-describe('measureLayout', () => {
158
- test('component.measureLayout(component, ...) invokes callback', async () => {
159
- const [[fooRef, barRef]] = await mockRenderKeys([['foo', 'bar']]);
160
-
161
- const successCallback = jest.fn();
162
- const failureCallback = jest.fn();
163
- fooRef.measureLayout(barRef, successCallback, failureCallback);
164
-
165
- expect(nativeFabricUIManager.measureLayout).toHaveBeenCalledTimes(1);
166
- expect(successCallback.mock.calls).toEqual([[1, 1, 100, 100]]);
167
- });
168
-
169
- test('unmounted.measureLayout(component, ...) does nothing', async () => {
170
- const [[fooRef, barRef]] = await mockRenderKeys([
171
- ['foo', 'bar'],
172
- ['foo', null],
173
- ]);
174
-
175
- const successCallback = jest.fn();
176
- const failureCallback = jest.fn();
177
- fooRef.measureLayout(barRef, successCallback, failureCallback);
178
-
179
- expect(nativeFabricUIManager.measureLayout).not.toHaveBeenCalled();
180
- expect(successCallback).not.toHaveBeenCalled();
181
- });
182
-
183
- test('component.measureLayout(unmounted, ...) does nothing', async () => {
184
- const [[fooRef, barRef]] = await mockRenderKeys([
185
- ['foo', 'bar'],
186
- [null, 'bar'],
187
- ]);
188
-
189
- const successCallback = jest.fn();
190
- const failureCallback = jest.fn();
191
- fooRef.measureLayout(barRef, successCallback, failureCallback);
192
-
193
- expect(nativeFabricUIManager.measureLayout).not.toHaveBeenCalled();
194
- expect(successCallback).not.toHaveBeenCalled();
195
- });
196
-
197
- test('unmounted.measureLayout(unmounted, ...) does nothing', async () => {
198
- const [[fooRef, barRef]] = await mockRenderKeys([['foo', 'bar'], null]);
199
-
200
- const successCallback = jest.fn();
201
- const failureCallback = jest.fn();
202
- fooRef.measureLayout(barRef, successCallback, failureCallback);
203
-
204
- expect(nativeFabricUIManager.measureLayout).not.toHaveBeenCalled();
205
- expect(successCallback).not.toHaveBeenCalled();
206
- });
207
-});
208
-
209
-describe('unstable_getBoundingClientRect', () => {
210
- test('component.unstable_getBoundingClientRect() returns DOMRect', async () => {
211
- const [[fooRef]] = await mockRenderKeys([['foo']]);
212
-
213
- const rect = fooRef.unstable_getBoundingClientRect();
214
-
215
- expect(nativeFabricUIManager.getBoundingClientRect).toHaveBeenCalledTimes(
216
- 1,
217
- );
218
- expect(rect.toJSON()).toMatchObject({
219
- x: 10,
220
- y: 10,
221
- width: 100,
222
- height: 100,
223
- });
224
- });
225
-
226
- test('unmounted.unstable_getBoundingClientRect() returns empty DOMRect', async () => {
227
- const [[fooRef]] = await mockRenderKeys([['foo'], null]);
228
-
229
- const rect = fooRef.unstable_getBoundingClientRect();
230
-
231
- expect(nativeFabricUIManager.getBoundingClientRect).not.toHaveBeenCalled();
232
- expect(rect.toJSON()).toMatchObject({x: 0, y: 0, width: 0, height: 0});
233
- });
234
-});
235
-
236
-describe('setNativeProps', () => {
237
- test('setNativeProps(...) invokes setNativeProps on Fabric UIManager', async () => {
238
- const {
239
- UIManager,
240
- } = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface');
241
-
242
- const [[fooRef]] = await mockRenderKeys([['foo']]);
243
- fooRef.setNativeProps({foo: 'baz'});
244
-
245
- expect(UIManager.updateView).not.toBeCalled();
246
- expect(nativeFabricUIManager.setNativeProps).toHaveBeenCalledTimes(1);
247
- });
248
-});
scripts/flow/react-native-host-hooks.js
+13
@@ -16,6 +16,7 @@ type __MeasureInWindowOnSuccessCallback = any;
16
type __MeasureLayoutOnSuccessCallback = any;
17
type __ReactNativeBaseComponentViewConfig = any;
18
type __ViewConfigGetter = any;
19
+type __ViewConfig = any;
20
21
// libdefs cannot actually import. This is supposed to be the type imported
22
// from 'react-native-renderer/src/legacy-events/TopLevelEventTypes';
@@ -143,6 +144,18 @@ declare module 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'
144
emit: (channel: string, event: RawEventEmitterEvent) => string,
145
...
146
};
147
+ declare export opaque type PublicInstance;
148
+ declare export function getNodeFromPublicInstance(
149
+ publicInstance: PublicInstance,
150
+ ): Object;
151
+ declare export function getNativeTagFromPublicInstance(
152
+ publicInstance: PublicInstance,
153
+ ): number;
154
+ declare export function createPublicInstance(
155
+ tag: number,
156
+ viewConfig: __ViewConfig,
157
+ internalInstanceHandle: mixed,
158
+ ): PublicInstance;
159
}
160
161
declare module 'react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore' {