Skip to content

Commit a431905

Browse files
rubennortefacebook-github-bot
authored andcommitted
Simplify RendererProxy and RendererImplementation to Fabric-only (facebook#56556)
Summary: Changelog: [internal] All Meta apps have migrated to Fabric, so we no longer need to support Paper in the renderer infrastructure. This commit simplifies: - RendererImplementation.js: Rewritten to only use Fabric renderer - RendererProxy.fb.js: Removed Paper-related exports - RendererProxy.js: Updated comment to reflect Fabric variants (profiling vs production) - FabricRendererImplementationWithProfiling.js: Removed Paper shims - Jest mock RendererProxy.js: Removed Paper exports Differential Revision: D101353113
1 parent 6a93982 commit a431905

4 files changed

Lines changed: 33 additions & 95 deletions

File tree

packages/jest-preset/jest/mocks/RendererProxy.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ const {
2323
isProfilingRenderer,
2424
renderElement,
2525
sendAccessibilityEvent,
26-
unmountComponentAtNodeAndRemoveContainer,
2726
unstable_batchedUpdates,
2827
} = jest.requireActual<TRendererImplementation>(
2928
'react-native/Libraries/ReactNative/RendererImplementation',
@@ -40,6 +39,5 @@ export {
4039
isProfilingRenderer,
4140
renderElement,
4241
sendAccessibilityEvent,
43-
unmountComponentAtNodeAndRemoveContainer,
4442
unstable_batchedUpdates,
4543
};

packages/react-native/Libraries/ReactNative/AppRegistryImpl.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import createPerformanceLogger from '../Utilities/createPerformanceLogger';
2626
import SceneTracker from '../Utilities/SceneTracker';
2727
import {coerceDisplayMode} from './DisplayMode';
2828
import HeadlessJsTaskError from './HeadlessJsTaskError';
29-
import {unmountComponentAtNodeAndRemoveContainer} from './RendererProxy';
3029
import invariant from 'invariant';
3130

3231
type TaskCanceller = () => void;
@@ -210,7 +209,9 @@ export function setSurfaceProps(
210209
* See https://reactnative.dev/docs/appregistry#unmountapplicationcomponentatroottag
211210
*/
212211
export function unmountApplicationComponentAtRootTag(rootTag: RootTag): void {
213-
unmountComponentAtNodeAndRemoveContainer(rootTag);
212+
console.error(
213+
'Unexpected call to unmountApplicationComponentAtRootTag in Fabric.',
214+
);
214215
}
215216

216217
/**

packages/react-native/Libraries/ReactNative/RendererImplementation.js

Lines changed: 26 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
import type {HostInstance} from '../../src/private/types/HostInstance';
1212
import typeof ReactFabricType from '../Renderer/shims/ReactFabric';
13-
import typeof ReactNativeType from '../Renderer/shims/ReactNative';
14-
import type {RootTag} from './RootTag';
1513

1614
import {
1715
onCaughtError,
@@ -21,7 +19,6 @@ import {
2119
import * as React from 'react';
2220

2321
let cachedFabricRenderer;
24-
let cachedPaperRenderer;
2522

2623
function getFabricRenderer(): ReactFabricType {
2724
if (cachedFabricRenderer == null) {
@@ -30,21 +27,10 @@ function getFabricRenderer(): ReactFabricType {
3027
return cachedFabricRenderer;
3128
}
3229

33-
function getPaperRenderer(): ReactNativeType {
34-
if (cachedPaperRenderer == null) {
35-
cachedPaperRenderer = require('../Renderer/shims/ReactNative').default;
36-
}
37-
return cachedPaperRenderer;
38-
}
39-
40-
const getMethod: (<MethodName extends keyof ReactFabricType>(
30+
const getMethod: <MethodName extends keyof ReactFabricType>(
4131
() => ReactFabricType,
4232
MethodName,
43-
) => ReactFabricType[MethodName]) &
44-
(<MethodName extends keyof ReactNativeType>(
45-
() => ReactNativeType,
46-
MethodName,
47-
) => ReactNativeType[MethodName]) = (getRenderer, methodName) => {
33+
) => ReactFabricType[MethodName] = (getRenderer, methodName) => {
4834
let cachedImpl;
4935

5036
// $FlowExpectedError[incompatible-type]
@@ -66,14 +52,7 @@ function getFabricMethod<MethodName extends keyof ReactFabricType>(
6652
return getMethod(getFabricRenderer, methodName);
6753
}
6854

69-
function getPaperMethod<MethodName extends keyof ReactNativeType>(
70-
methodName: MethodName,
71-
): ReactNativeType[MethodName] {
72-
return getMethod(getPaperRenderer, methodName);
73-
}
74-
7555
let cachedFabricRender;
76-
let cachedPaperRender;
7756

7857
export function renderElement({
7958
element,
@@ -86,84 +65,55 @@ export function renderElement({
8665
useFabric: boolean,
8766
useConcurrentRoot: boolean,
8867
}): void {
89-
if (useFabric) {
90-
if (cachedFabricRender == null) {
91-
cachedFabricRender = getFabricRenderer().render;
92-
}
93-
94-
cachedFabricRender(element, rootTag, null, useConcurrentRoot, {
95-
onCaughtError,
96-
onUncaughtError,
97-
onRecoverableError,
98-
});
99-
} else {
100-
if (cachedPaperRender == null) {
101-
cachedPaperRender = getPaperRenderer().render;
102-
}
103-
104-
cachedPaperRender(element, rootTag, undefined, {
105-
onCaughtError,
106-
onUncaughtError,
107-
onRecoverableError,
108-
});
68+
if (cachedFabricRender == null) {
69+
cachedFabricRender = getFabricRenderer().render;
10970
}
71+
72+
cachedFabricRender(element, rootTag, null, useConcurrentRoot, {
73+
onCaughtError,
74+
onUncaughtError,
75+
onRecoverableError,
76+
});
11077
}
11178

11279
let cachedFabricDispatchCommand;
113-
let cachedPaperDispatchCommand;
11480

11581
export function dispatchCommand(
11682
handle: HostInstance,
11783
command: string,
11884
args: Array<unknown>,
11985
): void {
120-
if (global.RN$Bridgeless === true) {
121-
// Note: this function has the same implementation in the legacy and new renderer.
122-
// However, evaluating the old renderer comes with some side effects.
123-
if (cachedFabricDispatchCommand == null) {
124-
cachedFabricDispatchCommand = getFabricRenderer().dispatchCommand;
125-
}
126-
127-
return cachedFabricDispatchCommand(handle, command, args);
128-
} else {
129-
if (cachedPaperDispatchCommand == null) {
130-
cachedPaperDispatchCommand = getPaperRenderer().dispatchCommand;
131-
}
132-
133-
return cachedPaperDispatchCommand(handle, command, args);
86+
if (cachedFabricDispatchCommand == null) {
87+
cachedFabricDispatchCommand = getFabricRenderer().dispatchCommand;
13488
}
89+
90+
return cachedFabricDispatchCommand(handle, command, args);
13591
}
13692

13793
export const findHostInstance_DEPRECATED: <
13894
TElementType extends React.ElementType,
13995
>(
14096
// $FlowExpectedError[incompatible-type]
14197
componentOrHandle: ?(React.ElementRef<TElementType> | number),
142-
) => ?HostInstance = getPaperMethod('findHostInstance_DEPRECATED');
98+
) => ?HostInstance = getFabricMethod('findHostInstance_DEPRECATED');
14399

144100
export const findNodeHandle: <TElementType extends React.ElementType>(
145101
// $FlowExpectedError[incompatible-type]
146102
componentOrHandle: ?(React.ElementRef<TElementType> | number),
147-
) => ?number = getPaperMethod('findNodeHandle');
103+
) => ?number = getFabricMethod('findNodeHandle');
148104

149-
export const sendAccessibilityEvent: ReactNativeType['sendAccessibilityEvent'] =
150-
getPaperMethod('sendAccessibilityEvent');
105+
export const sendAccessibilityEvent: ReactFabricType['sendAccessibilityEvent'] =
106+
getFabricMethod('sendAccessibilityEvent');
151107

152-
/**
153-
* This method is used by AppRegistry to unmount a root when using the old
154-
* React Native renderer (Paper).
155-
*/
156-
export const unmountComponentAtNodeAndRemoveContainer: (
157-
rootTag: RootTag,
158-
) => void =
159-
// $FlowExpectedError[incompatible-type]
160-
getPaperMethod('unmountComponentAtNodeAndRemoveContainer');
161-
162-
export const unstable_batchedUpdates: ReactNativeType['unstable_batchedUpdates'] =
163-
getPaperMethod('unstable_batchedUpdates');
108+
export function unstable_batchedUpdates<T>(
109+
fn: (bookkeeping: T) => void,
110+
bookkeeping: T,
111+
): void {
112+
fn(bookkeeping);
113+
}
164114

165-
export const isChildPublicInstance: ReactNativeType['isChildPublicInstance'] =
166-
getPaperMethod('isChildPublicInstance');
115+
export const isChildPublicInstance: ReactFabricType['isChildPublicInstance'] =
116+
getFabricMethod('isChildPublicInstance');
167117

168118
export const getNodeFromInternalInstanceHandle: ReactFabricType['getNodeFromInternalInstanceHandle'] =
169119
getFabricMethod('getNodeFromInternalInstanceHandle');

packages/react-native/Libraries/ReactNative/RendererProxy.js

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,8 @@
88
* @format
99
*/
1010

11-
/**
12-
* This module exists to allow apps to select their renderer implementation
13-
* (e.g.: Fabric-only, Paper-only) without having to pull all the renderer
14-
* implementations into their app bundle, which affects app size.
15-
*
16-
* By default, the setup will be:
17-
* -> RendererProxy
18-
* -> RendererImplementation (which uses Fabric or Paper depending on a flag at runtime)
19-
*
20-
* But this will allow a setup like this without duplicating logic:
21-
* -> RendererProxy (fork)
22-
* -> RendererImplementation (which uses Fabric or Paper depending on a flag at runtime)
23-
* or -> OtherImplementation (which uses Fabric only)
24-
*/
25-
11+
// This module allows app bundles to set up the appropriate Fabric renderer
12+
// variant (e.g., profiling vs production) before React Native is initialized.
13+
// The internal implementation (RendererProxy.fb.js) provides the indirection
14+
// needed to swap the renderer implementation at runtime.
2615
export * from './RendererImplementation';

0 commit comments

Comments
 (0)