From 036b0d4f17eff56ccc7d579b4a8b2a8adff515e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Tue, 19 Aug 2025 03:11:15 -0700 Subject: [PATCH 1/2] Remove nullability from NativePerformance module methods Differential Revision: D80453413 --- .../webapis/performance/Performance.js | 40 +++++-------------- .../performance/specs/NativePerformance.js | 8 ++-- 2 files changed, 15 insertions(+), 33 deletions(-) diff --git a/packages/react-native/src/private/webapis/performance/Performance.js b/packages/react-native/src/private/webapis/performance/Performance.js index 2a69d245cd58..65c66dd2359b 100644 --- a/packages/react-native/src/private/webapis/performance/Performance.js +++ b/packages/react-native/src/private/webapis/performance/Performance.js @@ -29,10 +29,7 @@ import { performanceEntryTypeToRaw, rawToPerformanceEntry, } from './internals/RawPerformanceEntry'; -import { - getCurrentTimeStamp, - warnNoNativePerformance, -} from './internals/Utilities'; +import {getCurrentTimeStamp} from './internals/Utilities'; import MemoryInfo from './MemoryInfo'; import ReactNativeStartupTiming from './ReactNativeStartupTiming'; import MaybeNativePerformance from './specs/NativePerformance'; @@ -78,18 +75,16 @@ const MEASURE_OPTIONS_REUSABLE_OBJECT: {...PerformanceMeasureInit} = { detail: undefined, }; -const getMarkTimeForMeasure = cachedGetMarkTime - ? (markName: string): number => { - const markTime = cachedGetMarkTime(markName); - if (markTime == null) { - throw new DOMException( - `Failed to execute 'measure' on 'Performance': The mark '${markName}' does not exist.`, - 'SyntaxError', - ); - } - return markTime; - } - : undefined; +const getMarkTimeForMeasure = (markName: string): number => { + const markTime = cachedGetMarkTime(markName); + if (markTime == null) { + throw new DOMException( + `Failed to execute 'measure' on 'Performance': The mark '${markName}' does not exist.`, + 'SyntaxError', + ); + } + return markTime; +}; /** * Partial implementation of the Performance interface for RN, @@ -151,11 +146,6 @@ export default class Performance { // Please run the benchmarks in `Performance-benchmarks-itest` to ensure // changes do not regress performance. - if (cachedReportMark === undefined) { - warnNoNativePerformance(); - return new PerformanceMark(markName, {startTime: 0}); - } - if (markName === undefined) { throw new TypeError( `Failed to execute 'mark' on 'Performance': 1 argument required, but only 0 present.`, @@ -225,14 +215,6 @@ export default class Performance { // Please run the benchmarks in `Performance-benchmarks-itest` to ensure // changes do not regress performance. - if ( - getMarkTimeForMeasure === undefined || - cachedReportMeasure === undefined - ) { - warnNoNativePerformance(); - return new PerformanceMeasure(measureName, {startTime: 0, duration: 0}); - } - let resolvedMeasureName: string; let resolvedStartTime: number; let resolvedDuration: number; diff --git a/packages/react-native/src/private/webapis/performance/specs/NativePerformance.js b/packages/react-native/src/private/webapis/performance/specs/NativePerformance.js index 879a957bd53e..4981b1a31d5e 100644 --- a/packages/react-native/src/private/webapis/performance/specs/NativePerformance.js +++ b/packages/react-native/src/private/webapis/performance/specs/NativePerformance.js @@ -54,14 +54,14 @@ export type PerformanceObserverInit = { export interface Spec extends TurboModule { +now: () => number; - +reportMark?: (name: string, startTime: number, entry: mixed) => void; - +reportMeasure?: ( + +reportMark: (name: string, startTime: number, entry: mixed) => void; + +reportMeasure: ( name: string, startTime: number, duration: number, entry: mixed, ) => void; - +getMarkTime?: (name: string) => ?number; + +getMarkTime: (name: string) => ?number; +clearMarks: (entryName?: string) => void; +clearMeasures: (entryName?: string) => void; +getEntries: () => $ReadOnlyArray; @@ -93,7 +93,7 @@ export interface Spec extends TurboModule { +getSupportedPerformanceEntryTypes: () => $ReadOnlyArray; - +clearEventCountsForTesting?: () => void; + +clearEventCountsForTesting: () => void; } export default (TurboModuleRegistry.get('NativePerformanceCxx'): ?Spec); From e3257e92e4e411dc9ff3df7c8096e9687bbc4a68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Tue, 19 Aug 2025 03:31:23 -0700 Subject: [PATCH 2/2] Remove nullability from NativeDOM.setNativeProps (#53331) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/53331 Changelog: [internal] This change was shipped 3 months ago so we can assume the native method will always have this method and don't need to keep backwards compatibility. Reviewed By: rshest Differential Revision: D80449031 --- .../ReactFabricPublicInstance-itest.js | 54 ------------------- .../webapis/dom/nodes/specs/NativeDOM.js | 17 ++---- 2 files changed, 5 insertions(+), 66 deletions(-) diff --git a/packages/react-native/Libraries/ReactNative/ReactFabricPublicInstance/__tests__/ReactFabricPublicInstance-itest.js b/packages/react-native/Libraries/ReactNative/ReactFabricPublicInstance/__tests__/ReactFabricPublicInstance-itest.js index a2960ebdcc44..1d0543d14c73 100644 --- a/packages/react-native/Libraries/ReactNative/ReactFabricPublicInstance/__tests__/ReactFabricPublicInstance-itest.js +++ b/packages/react-native/Libraries/ReactNative/ReactFabricPublicInstance/__tests__/ReactFabricPublicInstance-itest.js @@ -14,7 +14,6 @@ import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment'; import type {HostInstance} from 'react-native'; import ReactNativeElement from '../../../../src/private/webapis/dom/nodes/ReactNativeElement'; -import {getRawNativeDOMForTests} from '../../../../src/private/webapis/dom/nodes/specs/NativeDOM'; import TextInputState from '../../../Components/TextInput/TextInputState'; import View from '../../../Components/View/View'; import ReactFabricHostComponent from '../ReactFabricHostComponent'; @@ -349,58 +348,5 @@ describe('ReactFabricPublicInstance', () => { .toJSX(), ).toEqual(); }); - - // TODO: delete when NativeDOM.setNativeProps is NOT nullable. - // This logic is to ensure compatibility with old app versions without the native module method. - if (ReactNativeFeatureFlags.enableAccessToHostTreeInFabric()) { - let RawNativeDOM; - let originalSetNativeProps; - - beforeAll(() => { - RawNativeDOM = nullthrows(getRawNativeDOMForTests()); - originalSetNativeProps = RawNativeDOM.setNativeProps; - }); - - beforeEach(() => { - // $FlowExpectedError[cannot-write] - RawNativeDOM.setNativeProps = originalSetNativeProps; - }); - - it('should propagate changes to the host component (when NativeDOM.setNativeProps is not available)', () => { - // $FlowExpectedError[cannot-write] - RawNativeDOM.setNativeProps = null; - - expect(RawNativeDOM.setNativeProps).toBeNull(); - - const root = Fantom.createRoot(); - const nodeRef = createRef(); - - Fantom.runTask(() => { - root.render(); - }); - - expect( - root - .getRenderedOutput({ - props: ['testID'], - }) - .toJSX(), - ).toEqual(); - - const element = nullthrows(nodeRef.current); - - Fantom.runTask(() => { - element.setNativeProps({testID: 'second test id'}); - }); - - expect( - root - .getRenderedOutput({ - props: ['testID'], - }) - .toJSX(), - ).toEqual(); - }); - } }); }); diff --git a/packages/react-native/src/private/webapis/dom/nodes/specs/NativeDOM.js b/packages/react-native/src/private/webapis/dom/nodes/specs/NativeDOM.js index 588392d06ea1..e37815f31223 100644 --- a/packages/react-native/src/private/webapis/dom/nodes/specs/NativeDOM.js +++ b/packages/react-native/src/private/webapis/dom/nodes/specs/NativeDOM.js @@ -13,7 +13,6 @@ import type {Node as ShadowNode} from '../../../../../../Libraries/Renderer/shim import type {TurboModule} from '../../../../../../Libraries/TurboModule/RCTExport'; import type {InstanceHandle} from '../internals/NodeInternals'; -import {getFabricUIManager} from '../../../../../../Libraries/ReactNative/FabricUIManager'; import * as TurboModuleRegistry from '../../../../../../Libraries/TurboModule/TurboModuleRegistry'; import nullthrows from 'nullthrows'; @@ -165,7 +164,7 @@ export interface Spec extends TurboModule { * Legacy direct manipulation APIs (for `ReactNativeElement`). */ - +setNativeProps?: ( + +setNativeProps: ( nativeElementReference: mixed, updatePayload: mixed, ) => void; @@ -623,16 +622,10 @@ const NativeDOM: RefinedSpec = { * Legacy direct manipulation APIs */ setNativeProps(nativeNodeReference, updatePayload) { - // TODO: remove when RawNativeDOM.setNativeProps is NOT nullable. - if (RawNativeDOM?.setNativeProps == null) { - nullthrows(getFabricUIManager()).setNativeProps( - nativeNodeReference, - updatePayload, - ); - return; - } - - return RawNativeDOM.setNativeProps(nativeNodeReference, updatePayload); + return nullthrows(RawNativeDOM).setNativeProps( + nativeNodeReference, + updatePayload, + ); }, };