Skip to content

Commit eb616a1

Browse files
authored
Extract duplicated methods in Fabric and the legacy renderer to a shared module (#26319)
## Summary The following methods have exactly the same implementation on Fabric and the legacy renderer: * `findHostInstance_DEPRECATED` * `findNodeHandle` * `dispatchCommand` * `sendAccessibilityEvent` This just extracts those functions to a common module so they're easier to change (no need to sync changes in 2 files). ## How did you test this change? Existing tests (this is a refactor).
1 parent 49f7410 commit eb616a1

File tree

3 files changed

+179
-292
lines changed

3 files changed

+179
-292
lines changed

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

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

10-
import type {HostComponent} from './ReactNativeTypes';
1110
import type {ReactPortal, ReactNodeList} from 'shared/ReactTypes';
1211
import type {ElementRef, Element, ElementType} from 'react';
1312
import type {FiberRoot} from 'react-reconciler/src/ReactInternalTypes';
1413

1514
import './ReactFabricInjection';
1615

1716
import {
18-
findHostInstance,
19-
findHostInstanceWithWarning,
2017
batchedUpdates as batchedUpdatesImpl,
2118
discreteUpdates,
2219
createContainer,
@@ -29,159 +26,19 @@ import {createPortal as createPortalImpl} from 'react-reconciler/src/ReactPortal
2926
import {setBatchingImplementation} from './legacy-events/ReactGenericBatching';
3027
import ReactVersion from 'shared/ReactVersion';
3128

32-
// Modules provided by RN:
33-
import {
34-
UIManager,
35-
legacySendAccessibilityEvent,
36-
} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
37-
3829
import {getClosestInstanceFromNode} from './ReactFabricComponentTree';
3930
import {
4031
getInspectorDataForViewTag,
4132
getInspectorDataForViewAtPoint,
4233
getInspectorDataForInstance,
4334
} from './ReactNativeFiberInspector';
4435
import {LegacyRoot, ConcurrentRoot} from 'react-reconciler/src/ReactRootTags';
45-
import ReactSharedInternals from 'shared/ReactSharedInternals';
46-
import getComponentNameFromType from 'shared/getComponentNameFromType';
47-
48-
const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
49-
50-
function findHostInstance_DEPRECATED<TElementType: ElementType>(
51-
componentOrHandle: ?(ElementRef<TElementType> | number),
52-
): ?ElementRef<HostComponent<mixed>> {
53-
if (__DEV__) {
54-
const owner = ReactCurrentOwner.current;
55-
if (owner !== null && owner.stateNode !== null) {
56-
if (!owner.stateNode._warnedAboutRefsInRender) {
57-
console.error(
58-
'%s is accessing findNodeHandle inside its render(). ' +
59-
'render() should be a pure function of props and state. It should ' +
60-
'never access something that requires stale data from the previous ' +
61-
'render, such as refs. Move this logic to componentDidMount and ' +
62-
'componentDidUpdate instead.',
63-
getComponentNameFromType(owner.type) || 'A component',
64-
);
65-
}
66-
67-
owner.stateNode._warnedAboutRefsInRender = true;
68-
}
69-
}
70-
if (componentOrHandle == null) {
71-
return null;
72-
}
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;
77-
}
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-
let hostInstance;
84-
if (__DEV__) {
85-
hostInstance = findHostInstanceWithWarning(
86-
componentOrHandle,
87-
'findHostInstance_DEPRECATED',
88-
);
89-
} else {
90-
hostInstance = findHostInstance(componentOrHandle);
91-
}
92-
93-
return hostInstance;
94-
}
95-
96-
function findNodeHandle(componentOrHandle: any): ?number {
97-
if (__DEV__) {
98-
const owner = ReactCurrentOwner.current;
99-
if (owner !== null && owner.stateNode !== null) {
100-
if (!owner.stateNode._warnedAboutRefsInRender) {
101-
console.error(
102-
'%s is accessing findNodeHandle inside its render(). ' +
103-
'render() should be a pure function of props and state. It should ' +
104-
'never access something that requires stale data from the previous ' +
105-
'render, such as refs. Move this logic to componentDidMount and ' +
106-
'componentDidUpdate instead.',
107-
getComponentNameFromType(owner.type) || 'A component',
108-
);
109-
}
110-
111-
owner.stateNode._warnedAboutRefsInRender = true;
112-
}
113-
}
114-
if (componentOrHandle == null) {
115-
return null;
116-
}
117-
if (typeof componentOrHandle === 'number') {
118-
// Already a node handle
119-
return componentOrHandle;
120-
}
121-
if (componentOrHandle._nativeTag) {
122-
return componentOrHandle._nativeTag;
123-
}
124-
if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) {
125-
return componentOrHandle.canonical._nativeTag;
126-
}
127-
let hostInstance;
128-
if (__DEV__) {
129-
hostInstance = findHostInstanceWithWarning(
130-
componentOrHandle,
131-
'findNodeHandle',
132-
);
133-
} else {
134-
hostInstance = findHostInstance(componentOrHandle);
135-
}
136-
137-
if (hostInstance == null) {
138-
return hostInstance;
139-
}
140-
141-
return hostInstance._nativeTag;
142-
}
143-
144-
function dispatchCommand(handle: any, command: string, args: Array<any>) {
145-
if (handle._nativeTag == null) {
146-
if (__DEV__) {
147-
console.error(
148-
"dispatchCommand was called with a ref that isn't a " +
149-
'native component. Use React.forwardRef to get access to the underlying native component',
150-
);
151-
}
152-
return;
153-
}
154-
155-
if (handle._internalInstanceHandle != null) {
156-
const {stateNode} = handle._internalInstanceHandle;
157-
if (stateNode != null) {
158-
nativeFabricUIManager.dispatchCommand(stateNode.node, command, args);
159-
}
160-
} else {
161-
UIManager.dispatchViewManagerCommand(handle._nativeTag, command, args);
162-
}
163-
}
164-
165-
function sendAccessibilityEvent(handle: any, eventType: string) {
166-
if (handle._nativeTag == null) {
167-
if (__DEV__) {
168-
console.error(
169-
"sendAccessibilityEvent was called with a ref that isn't a " +
170-
'native component. Use React.forwardRef to get access to the underlying native component',
171-
);
172-
}
173-
return;
174-
}
175-
176-
if (handle._internalInstanceHandle != null) {
177-
const {stateNode} = handle._internalInstanceHandle;
178-
if (stateNode != null) {
179-
nativeFabricUIManager.sendAccessibilityEvent(stateNode.node, eventType);
180-
}
181-
} else {
182-
legacySendAccessibilityEvent(handle._nativeTag, eventType);
183-
}
184-
}
36+
import {
37+
findHostInstance_DEPRECATED,
38+
findNodeHandle,
39+
dispatchCommand,
40+
sendAccessibilityEvent,
41+
} from './ReactNativePublicCompat';
18542

18643
// $FlowFixMe[missing-local-annot]
18744
function onRecoverableError(error) {
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
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
8+
*/
9+
10+
import type {HostComponent} from './ReactNativeTypes';
11+
import type {ElementRef, ElementType} from 'react';
12+
13+
// Modules provided by RN:
14+
import {
15+
UIManager,
16+
legacySendAccessibilityEvent,
17+
} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
18+
19+
import {
20+
findHostInstance,
21+
findHostInstanceWithWarning,
22+
} from 'react-reconciler/src/ReactFiberReconciler';
23+
import ReactSharedInternals from 'shared/ReactSharedInternals';
24+
import getComponentNameFromType from 'shared/getComponentNameFromType';
25+
26+
const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
27+
28+
export function findHostInstance_DEPRECATED<TElementType: ElementType>(
29+
componentOrHandle: ?(ElementRef<TElementType> | number),
30+
): ?ElementRef<HostComponent<mixed>> {
31+
if (__DEV__) {
32+
const owner = ReactCurrentOwner.current;
33+
if (owner !== null && owner.stateNode !== null) {
34+
if (!owner.stateNode._warnedAboutRefsInRender) {
35+
console.error(
36+
'%s is accessing findNodeHandle inside its render(). ' +
37+
'render() should be a pure function of props and state. It should ' +
38+
'never access something that requires stale data from the previous ' +
39+
'render, such as refs. Move this logic to componentDidMount and ' +
40+
'componentDidUpdate instead.',
41+
getComponentNameFromType(owner.type) || 'A component',
42+
);
43+
}
44+
45+
owner.stateNode._warnedAboutRefsInRender = true;
46+
}
47+
}
48+
if (componentOrHandle == null) {
49+
return null;
50+
}
51+
// $FlowFixMe Flow has hardcoded values for React DOM that don't work with RN
52+
if (componentOrHandle._nativeTag) {
53+
// $FlowFixMe Flow has hardcoded values for React DOM that don't work with RN
54+
return componentOrHandle;
55+
}
56+
// $FlowFixMe Flow has hardcoded values for React DOM that don't work with RN
57+
if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) {
58+
// $FlowFixMe Flow has hardcoded values for React DOM that don't work with RN
59+
return componentOrHandle.canonical;
60+
}
61+
let hostInstance;
62+
if (__DEV__) {
63+
hostInstance = findHostInstanceWithWarning(
64+
componentOrHandle,
65+
'findHostInstance_DEPRECATED',
66+
);
67+
} else {
68+
hostInstance = findHostInstance(componentOrHandle);
69+
}
70+
71+
return hostInstance;
72+
}
73+
74+
export function findNodeHandle(componentOrHandle: any): ?number {
75+
if (__DEV__) {
76+
const owner = ReactCurrentOwner.current;
77+
if (owner !== null && owner.stateNode !== null) {
78+
if (!owner.stateNode._warnedAboutRefsInRender) {
79+
console.error(
80+
'%s is accessing findNodeHandle inside its render(). ' +
81+
'render() should be a pure function of props and state. It should ' +
82+
'never access something that requires stale data from the previous ' +
83+
'render, such as refs. Move this logic to componentDidMount and ' +
84+
'componentDidUpdate instead.',
85+
getComponentNameFromType(owner.type) || 'A component',
86+
);
87+
}
88+
89+
owner.stateNode._warnedAboutRefsInRender = true;
90+
}
91+
}
92+
if (componentOrHandle == null) {
93+
return null;
94+
}
95+
if (typeof componentOrHandle === 'number') {
96+
// Already a node handle
97+
return componentOrHandle;
98+
}
99+
if (componentOrHandle._nativeTag) {
100+
return componentOrHandle._nativeTag;
101+
}
102+
if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) {
103+
return componentOrHandle.canonical._nativeTag;
104+
}
105+
let hostInstance;
106+
if (__DEV__) {
107+
hostInstance = findHostInstanceWithWarning(
108+
componentOrHandle,
109+
'findNodeHandle',
110+
);
111+
} else {
112+
hostInstance = findHostInstance(componentOrHandle);
113+
}
114+
115+
if (hostInstance == null) {
116+
return hostInstance;
117+
}
118+
119+
return hostInstance._nativeTag;
120+
}
121+
122+
export function dispatchCommand(
123+
handle: any,
124+
command: string,
125+
args: Array<any>,
126+
) {
127+
if (handle._nativeTag == null) {
128+
if (__DEV__) {
129+
console.error(
130+
"dispatchCommand was called with a ref that isn't a " +
131+
'native component. Use React.forwardRef to get access to the underlying native component',
132+
);
133+
}
134+
return;
135+
}
136+
137+
if (handle._internalInstanceHandle != null) {
138+
const {stateNode} = handle._internalInstanceHandle;
139+
if (stateNode != null) {
140+
nativeFabricUIManager.dispatchCommand(stateNode.node, command, args);
141+
}
142+
} else {
143+
UIManager.dispatchViewManagerCommand(handle._nativeTag, command, args);
144+
}
145+
}
146+
147+
export function sendAccessibilityEvent(handle: any, eventType: string) {
148+
if (handle._nativeTag == null) {
149+
if (__DEV__) {
150+
console.error(
151+
"sendAccessibilityEvent was called with a ref that isn't a " +
152+
'native component. Use React.forwardRef to get access to the underlying native component',
153+
);
154+
}
155+
return;
156+
}
157+
158+
if (handle._internalInstanceHandle != null) {
159+
const {stateNode} = handle._internalInstanceHandle;
160+
if (stateNode != null) {
161+
nativeFabricUIManager.sendAccessibilityEvent(stateNode.node, eventType);
162+
}
163+
} else {
164+
legacySendAccessibilityEvent(handle._nativeTag, eventType);
165+
}
166+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy