Forward port away from deprecated React.ElementRef to React.ComponentRef (#54274)

Summary:
React v19 deprecated React.ElementRef and recommends using React.ComponentRef

This appears to work just fine, with no other changes other than the type, with the exception of the Codegen phase which makes no allowance for ComponentRef during parsing

I altered the typescript and flow parsers to accept the new ComponentRef as well as the old ElementRef

- Fixes https://github.com/facebook/react-native/issues/54272

## Changelog:

[INTERNAL][DEPRECATED] - use React.ComponentRef in codegen in place of React.ElementRef

Pull Request resolved: https://github.com/facebook/react-native/pull/54274

Test Plan: This is mostly checked in jest tests, I updated the fixtures to send ComponentRef through, and I updated the snapshots to expect a message that indicates either ElementRef or ComponentRef are expected

Reviewed By: javache

Differential Revision: D85556329

Pulled By: cipolleschi

fbshipit-source-id: 0ca4e3929743746da0bde1bfb0e05500db0594f7
This commit is contained in:
Mike Hardy
2025-11-10 10:58:44 -08:00
committed by meta-codesync[bot]
parent 581d643a9e
commit abd3bfb5c9
3 changed files with 19 additions and 18 deletions
@@ -1062,17 +1062,17 @@ export interface ModuleProps extends ViewProps {
type NativeType = HostComponent<ModuleProps>;
interface NativeCommands {
readonly handleRootTag: (viewRef: React.ElementRef<NativeType>, rootTag: RootTag) => void;
readonly hotspotUpdate: (viewRef: React.ElementRef<NativeType>, x: Int32, y: Int32) => void;
readonly handleRootTag: (viewRef: React.ComponentRef<NativeType>, rootTag: RootTag) => void;
readonly hotspotUpdate: (viewRef: React.ComponentRef<NativeType>, x: Int32, y: Int32) => void;
scrollTo(
viewRef: React.ElementRef<NativeType>,
viewRef: React.ComponentRef<NativeType>,
x: Float,
y: Int32,
z: Double,
animated: boolean,
): void;
readonly arrayArgs: (
viewRef: React.ElementRef<NativeType>,
viewRef: React.ComponentRef<NativeType>,
booleanArray: ReadOnlyArray<boolean>,
stringArray: ReadOnlyArray<string>,
floatArray: ReadOnlyArray<Float>,
@@ -1122,12 +1122,12 @@ export interface ModuleProps extends ViewProps {
type NativeType = HostComponent<ModuleProps>;
export type ScrollTo = (
viewRef: React.ElementRef<NativeType>,
viewRef: React.ComponentRef<NativeType>,
y: Int,
animated: Boolean,
) => Void;
export type AddOverlays = (
viewRef: React.ElementRef<NativeType>,
viewRef: React.ComponentRef<NativeType>,
overlayColorsReadOnly: ReadOnlyArray<string>,
overlayColorsArray: Array<string>,
overlayColorsArrayAnnotation: string[],
@@ -1193,7 +1193,7 @@ export interface ModuleNativeState {
type NativeType = HostComponent<ModuleProps>;
export type ScrollTo = (viewRef: React.ElementRef<NativeType>, y: Int, animated: Boolean) => Void;
export type ScrollTo = (viewRef: React.ComponentRef<NativeType>, y: Int, animated: Boolean) => Void;
interface NativeCommands {
readonly scrollTo: ScrollTo;
@@ -2184,17 +2184,17 @@ export interface ModuleProps extends ViewProps {
type NativeType = HostComponent<ModuleProps>;
interface NativeCommands {
readonly handleRootTag: (viewRef: React.ElementRef<NativeType>, rootTag: RootTag) => void;
readonly hotspotUpdate: (viewRef: React.ElementRef<NativeType>, x: CodegenTypes.Int32, y: CodegenTypes.Int32) => void;
readonly handleRootTag: (viewRef: React.ComponentRef<NativeType>, rootTag: RootTag) => void;
readonly hotspotUpdate: (viewRef: React.ComponentRef<NativeType>, x: CodegenTypes.Int32, y: CodegenTypes.Int32) => void;
scrollTo(
viewRef: React.ElementRef<NativeType>,
viewRef: React.ComponentRef<NativeType>,
x: CodegenTypes.Float,
y: CodegenTypes.Int32,
z: CodegenTypes.Double,
animated: boolean,
): void;
readonly arrayArgs: (
viewRef: React.ElementRef<NativeType>,
viewRef: React.ComponentRef<NativeType>,
booleanArray: ReadOnlyArray<boolean>,
stringArray: ReadOnlyArray<string>,
floatArray: ReadOnlyArray<CodegenTypes.Float>,
@@ -2243,12 +2243,12 @@ export interface ModuleProps extends ViewProps {
type NativeType = HostComponent<ModuleProps>;
export type ScrollTo = (
viewRef: React.ElementRef<NativeType>,
viewRef: React.ComponentRef<NativeType>,
y: Int,
animated: Boolean,
) => Void;
export type AddOverlays = (
viewRef: React.ElementRef<NativeType>,
viewRef: React.ComponentRef<NativeType>,
overlayColorsReadOnly: ReadOnlyArray<string>,
overlayColorsArray: Array<string>,
overlayColorsArrayAnnotation: string[],
@@ -2310,7 +2310,7 @@ export interface ModuleNativeState {
type NativeType = HostComponent<ModuleProps>;
export type ScrollTo = (viewRef: React.ElementRef<NativeType>, y: Int, animated: Boolean) => Void;
export type ScrollTo = (viewRef: React.ComponentRef<NativeType>, y: Int, animated: Boolean) => Void;
interface NativeCommands {
readonly scrollTo: ScrollTo;
@@ -6,11 +6,11 @@ exports[`RN Codegen TypeScript Parser Fails with error message COMMANDS_DEFINED_
exports[`RN Codegen TypeScript Parser Fails with error message COMMANDS_DEFINED_WITH_MISMATCHED_METHOD_NAMES 1`] = `"codegenNativeCommands expected the same supportedCommands specified in the NativeCommands interface: hotspotUpdate, scrollTo"`;
exports[`RN Codegen TypeScript Parser Fails with error message COMMANDS_DEFINED_WITH_NULLABLE_REF 1`] = `"The first argument of method hotspotUpdate must be of type React.ElementRef<>"`;
exports[`RN Codegen TypeScript Parser Fails with error message COMMANDS_DEFINED_WITH_NULLABLE_REF 1`] = `"The first argument of method hotspotUpdate must be of type React.ElementRef<> or React.ComponentRef<>"`;
exports[`RN Codegen TypeScript Parser Fails with error message COMMANDS_DEFINED_WITHOUT_METHOD_NAMES 1`] = `"codegenNativeCommands must be passed options including the supported commands"`;
exports[`RN Codegen TypeScript Parser Fails with error message COMMANDS_DEFINED_WITHOUT_REF 1`] = `"The first argument of method hotspotUpdate must be of type React.ElementRef<>"`;
exports[`RN Codegen TypeScript Parser Fails with error message COMMANDS_DEFINED_WITHOUT_REF 1`] = `"The first argument of method hotspotUpdate must be of type React.ElementRef<> or React.ComponentRef<>"`;
exports[`RN Codegen TypeScript Parser Fails with error message NON_OPTIONAL_KEY_WITH_DEFAULT_VALUE 1`] = `"key required_key_with_default must be optional if used with WithDefault<> annotation"`;
@@ -38,11 +38,12 @@ function buildCommandSchemaInternal(
firstParam.typeAnnotation != null &&
firstParam.typeAnnotation.type === 'TSTypeReference' &&
firstParam.typeAnnotation.typeName.left?.name === 'React' &&
firstParam.typeAnnotation.typeName.right?.name === 'ElementRef'
(firstParam.typeAnnotation.typeName.right?.name === 'ElementRef' ||
firstParam.typeAnnotation.typeName.right?.name === 'ComponentRef')
)
) {
throw new Error(
`The first argument of method ${name} must be of type React.ElementRef<>`,
`The first argument of method ${name} must be of type React.ElementRef<> or React.ComponentRef<>`,
);
}