From 5b5cfd735614d227917a9623cd7e19f1eda55358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Tue, 28 Apr 2026 03:58:11 -0700 Subject: [PATCH] Improve typing of `renderApplication` Summary: General typing improvements to the `renderApplication` module: - Refactors `renderApplication` to take a single options object instead of positional arguments, and removes the unused `fabric` and `_unused` parameters. The `fabric` parameter was already always treated as `true` internally, and the `_unused` slot was a reserved positional placeholder for a removed `scopedPerformanceLogger` argument. - Migrates the file to `flow strict-local`. - Types `RootComponent` and `WrapperComponent` using component syntax instead of `React.ComponentType`. - Replaces `rootTag: any` with `number | RootTag`, normalizing via the existing `createRootTag` helper for `` and `Number()` for `Renderer.renderElement`. - Simplifies `ActivityType` (drops the unnecessary spread) and tightens null/boolean checks (`debugName != null`, `useOffscreen === true`). Exports a new `RenderApplicationOptions` type and updates all internal callers accordingly. Changelog: [Internal] Reviewed By: javache Differential Revision: D102325691 --- .../Libraries/ReactNative/AppRegistryImpl.js | 22 ++++----- .../ReactNative/RendererImplementation.js | 6 ++- .../ReactNative/renderApplication.js | 46 ++++++++++--------- 3 files changed, 39 insertions(+), 35 deletions(-) diff --git a/packages/react-native/Libraries/ReactNative/AppRegistryImpl.js b/packages/react-native/Libraries/ReactNative/AppRegistryImpl.js index e27c8acce10..010b1f5b8d6 100644 --- a/packages/react-native/Libraries/ReactNative/AppRegistryImpl.js +++ b/packages/react-native/Libraries/ReactNative/AppRegistryImpl.js @@ -83,21 +83,21 @@ export function registerComponent( ): string { runnables[appKey] = (appParameters, displayMode) => { const renderApplication = require('./renderApplication').default; - renderApplication( - componentProviderInstrumentationHook( + renderApplication({ + RootComponent: componentProviderInstrumentationHook( componentProvider, DeprecatedPerformanceLoggerStub, ), - appParameters.initialProps, - appParameters.rootTag, - wrapperComponentProvider && wrapperComponentProvider(appParameters), - rootViewStyleProvider && rootViewStyleProvider(appParameters), - true, // fabric - deprecated, always true - undefined, // formerly scopedPerformanceLogger; reserved positional slot - appKey === 'LogBox', // is logbox - appKey, + initialProps: appParameters.initialProps, + rootTag: appParameters.rootTag, + WrapperComponent: + wrapperComponentProvider && wrapperComponentProvider(appParameters), + rootViewStyle: + rootViewStyleProvider && rootViewStyleProvider(appParameters), + isLogBox: appKey === 'LogBox', + debugName: appKey, displayMode, - ); + }); }; if (section) { sections[appKey] = runnables[appKey]; diff --git a/packages/react-native/Libraries/ReactNative/RendererImplementation.js b/packages/react-native/Libraries/ReactNative/RendererImplementation.js index 31c945ebfac..cd4a835d7af 100644 --- a/packages/react-native/Libraries/ReactNative/RendererImplementation.js +++ b/packages/react-native/Libraries/ReactNative/RendererImplementation.js @@ -8,6 +8,8 @@ * @format */ +import type {RootTag} from './RootTag'; + import { onCaughtError, onRecoverableError, @@ -21,11 +23,11 @@ export function renderElement({ rootTag, }: { element: React.MixedElement, - rootTag: number, + rootTag: RootTag, }): void { ReactFabric.render( element, - rootTag, + Number(rootTag), /* callback */ null, /* useConcurrentRoot */ true, { diff --git a/packages/react-native/Libraries/ReactNative/renderApplication.js b/packages/react-native/Libraries/ReactNative/renderApplication.js index 2e33865734d..c7b403936cd 100644 --- a/packages/react-native/Libraries/ReactNative/renderApplication.js +++ b/packages/react-native/Libraries/ReactNative/renderApplication.js @@ -4,47 +4,49 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow + * @flow strict-local * @format */ import type {ViewStyleProp} from '../StyleSheet/StyleSheet'; +import type {RootTag} from './RootTag'; import AppContainer from './AppContainer'; import DisplayMode, {type DisplayModeType} from './DisplayMode'; import getCachedComponentWithDebugName from './getCachedComponentWithDebugName'; import * as Renderer from './RendererProxy'; +import {createRootTag} from './RootTag'; import invariant from 'invariant'; import * as React from 'react'; // require BackHandler so it sets the default handler that exits the app if no listeners respond import '../Utilities/BackHandler'; -type ActivityType = component( - ...{ - mode: 'visible' | 'hidden', - children: React.Node, - } -); +type ActivityType = component(mode: 'visible' | 'hidden', children: React.Node); -export default function renderApplication( - RootComponent: React.ComponentType, +export type RenderApplicationOptions = { + RootComponent: component(...Props), initialProps: Props, - rootTag: any, - WrapperComponent?: ?React.ComponentType, + rootTag: number | RootTag, + WrapperComponent?: ?component(initialProps: Props, children: React.Node), rootViewStyle?: ?ViewStyleProp, - // Keep this parameter for backwards compatibility only. It is always treated as - // true internally. - fabric?: true | void, - // Reserved positional slot (formerly `scopedPerformanceLogger`). Preserved so - // existing callers that supply this argument continue to type-check; the - // value is ignored. - _unused?: void, isLogBox?: boolean, debugName?: string, displayMode?: ?DisplayModeType, useOffscreen?: boolean, -) { +}; + +export default function renderApplication({ + RootComponent, + initialProps, + rootTag, + WrapperComponent, + rootViewStyle, + isLogBox, + debugName, + displayMode, + useOffscreen, +}: RenderApplicationOptions) { invariant(rootTag, 'Expect to have a valid rootTag, instead got ', rootTag); let renderable: React.MixedElement = ( @@ -58,7 +60,7 @@ export default function renderApplication( ); - if (__DEV__ && debugName) { + if (__DEV__ && debugName != null) { const RootComponentWithMeaningfulName = getCachedComponentWithDebugName( `${debugName}(RootComponent)`, ); @@ -69,7 +71,7 @@ export default function renderApplication( ); } - if (useOffscreen && displayMode != null) { + if (useOffscreen === true && displayMode != null) { // $FlowFixMe[incompatible-type] // $FlowFixMe[missing-export] // $FlowFixMe[prop-missing] `unstable_Activity` is not yet in the React types. @@ -85,6 +87,6 @@ export default function renderApplication( Renderer.renderElement({ element: renderable, - rootTag, + rootTag: createRootTag(rootTag), }); }