react / react/react-native

Fabric component: codegen drops optional state for component properties and in events properties

Abierto
#49,920 26 comentarios 6 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Needs: Triage :mag: Newer Patch Available Tech: Codegen Type: New Architecture
Lenguaje dominante
C++
Estrellas
127k
Forks
25.3k
Merge medio
1 d 23 h
PR fusionados (30 d)
4

Descripción

Description

When adding optional values to the specs for a Fabric component, these optionals are always bridged with a default value and as a result are always defined and no longer optional.

Example spec:

type Prop1 = Readonly<{
    propContent: string;
    propOptionalContent1?: string;
    propOptionalContent2?: string;
}>;
type Prop2 = Readonly<{
    propContent: string;
    propOptionalContent1?: string;
    propOptionalContent2?: string;
}>;
export type NativeEvent1 = Readonly<{
    nativeEventContent: string;
    nativeEventOptionalContent1?: string;
    nativeEventOptionalContent2?: string;
}>;
export type NativeEvent2 = Readonly<{
    nativeEventContent: string;
    nativeEventOptionalContent1?: string;
    nativeEventOptionalContent2?: string;
}>;
export interface NewArchViewProps extends ViewProps {
    prop1: Prop1;
    prop2: Prop2;
    onNativeEvent1: DirectEventHandler<NativeEvent1>;
    onNativeEvent2: DirectEventHandler<NativeEvent2>;
}

Codegen creates:

struct NewArchViewProp1Struct {
  std::string propContent{};
  std::string propOptionalContent1{};
  std::string propOptionalContent2{};
};
struct NewArchViewProp2Struct {
  std::string propContent{};
  std::string propOptionalContent1{};
  std::string propOptionalContent2{};
};
struct OnNativeEvent1 {
  std::string nativeEventContent;
  std::string nativeEventOptionalContent1;
  std::string nativeEventOptionalContent2;
};
struct OnNativeEvent2 {
  std::string nativeEventContent;
  std::string nativeEventOptionalContent1;
  std::string nativeEventOptionalContent2;
};

Every time an optional value is left out on 1 side of the bridge, the other side receives a default value (e.g optional string is filled in with empty string ""). Setting a default using WithDefault<> gives control over this default, but still does not respect the optional status of the properties.

As a result the old architecture versus the new architecture result in completely different objects being bridged. One has optional data where the other is always prop complete but with defaults.

Steps to reproduce

Add the above specs to a new arch enabled project and check the generated props.h and EventEmmiter.h for the generated code.

The linked reproducer has these in place.

React Native Version

0.76.7

Affected Platforms

Runtime - iOS

Areas

Codegen

Output of npx @react-native-community/cli info
System:
  OS: macOS 15.0.1
  CPU: (8) arm64 Apple M1 Pro
  Memory: 298.75 MB / 32.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 22.11.0
    path: ~/.nvm/versions/node/v22.11.0/bin/node
  Yarn:
    version: 1.22.22
    path: ~/.nvm/versions/node/v22.11.0/bin/yarn
  npm:
    version: 10.9.0
    path: ~/.nvm/versions/node/v22.11.0/bin/npm
  Watchman:
    version: 2024.08.19.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.16.2
    path: /opt/homebrew/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.2
      - iOS 18.2
      - macOS 15.2
      - tvOS 18.2
      - visionOS 2.2
      - watchOS 11.2
  Android SDK: Not Found
IDEs:
  Android Studio: 2024.1 AI-241.18034.62.2411.12169540
  Xcode:
    version: 16.2/16C5032a
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.14
    path: /Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home/bin/javac
  Ruby:
    version: 3.3.5
    path: /opt/homebrew/opt/ruby/bin/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 15.0.1
    wanted: 15.0.1
  react:
    installed: 18.3.1
    wanted: 18.3.1
  react-native:
    installed: 0.76.5
    wanted: 0.76.5
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: true
  newArchEnabled: true
Stacktrace or Logs
Example logs from the reproducer (reproducer/no-optionals branch) showing empty strings being bridged instead of remaining optional:

'nativeEvent1 optionalContent1 received:', '76BF877F-B476-4DB6-B961-C0DDA76B91E1'
'nativeEvent1 optionalContent2 received:', '24E3266D-7451-40E4-8A38-B5931A9ACDD1'
'nativeEvent2 optionalContent1 received:', ''
'nativeEvent2 optionalContent2 received:', ''
propOptionalContent1: optional1
propOptionalContent2: optional2
propOptionalContent1:
propOptionalContent2:
Reproducer

https://github.com/wvanhaevre/NewArchReproducer/tree/reproducer/no-optionals

Screenshots and Videos

No response

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con las especificaciones de componentes y eventos de TypeScript del issue y, a continuación, reproduce la salida en los props.h y EventEmmiter.h generados utilizando la rama reproducer/no-optionals del reproducer enlazado. Sigue el tratamiento de las propiedades opcionales en codegen y compara los props y eventos generados con el ejemplo. Se considera terminado cuando los valores opcionales omitidos siguen siendo opcionales en lugar de convertirse en valores inicializados por defecto al otro lado del bridge.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
cpp, react-native, typescript
Área
mobile, tooling
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Tranquilo
Claridad
Bastante claro
Aptitud para principiantes
48/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.