Saltar al contenido principal

React Native 0.77: Nuevas funciones de estilos, compatibilidad con páginas de 16KB en Android y plantilla Swift

· 15 min de lectura
Vojtech Novak
Vojtech Novak
Software Engineer @ Expo
Mazen Chami
Mazen Chami
Software Engineer @ InfiniteRed
Blake Friedman
Blake Friedman
Software Engineer @ Meta
Rob Hogan
Rob Hogan
Software Engineer @ Meta
Traducción Beta No Oficial

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

¡Hoy nos complace anunciar el lanzamiento de React Native 0.77!

Esta versión incluye varias funciones: nuevas capacidades de estilos como soporte para display: contents, boxSizing, mixBlendMode y propiedades relacionadas con outline para ofrecer más opciones de diseño; compatibilidad con páginas de 16KB en Android para adaptarse a dispositivos más nuevos. También estamos modernizando la plantilla comunitaria migrándola a Swift, manteniendo la compatibilidad con Objective-C para desarrolladores que lo prefieran.

Lo más destacado

Cambios importantes

Lo más destacado

Nuevas funciones CSS para mejores diseños, dimensiones y mezclas

React Native 0.77 avanza en nuestro objetivo de alinear React Native con la web. Hemos añadido soporte para nuevas propiedades CSS que te darán más control sobre el diseño, dimensiones y mezclas de tu aplicación. Estos cambios pueden ayudar a simplificar diseños complejos, añadir textura y hacer tu aplicación más accesible.

información

Todas estas nuevas funciones solo están disponibles para la Nueva Arquitectura.

Diseños más simples con display: contents

La propiedad display: contents permite que un elemento desaparezca de la estructura de diseño mientras sus hijos siguen renderizándose como si fueran hijos directos del elemento padre. Es útil para aplicar estilos a elementos hijos sin afectar el diseño, al crear componentes envoltorios que deben manejar eventos, o cuando necesitas interactuar con el ShadowTree.

Técnicamente, display: contents renderiza un elemento sin generar una caja de diseño, pero preserva las cajas de diseño de sus elementos hijos. El elemento con display: contents se elimina efectivamente de la jerarquía de vistas.

Veamos este ejemplo donde queremos mostrar una alerta al presionar un widget. Tenemos un Widget rojo dentro de una vista contenedora:

Container.jsx
function Container() {
return (
<View style={styles.container}>
<Widget />
</View>
);
}

configuración de display contents

Ahora construyamos un nuevo componente envoltorio Alerting, con el objetivo de alertar al usuario cuando se presione un componente debajo de él, usando eventos de puntero experimentales. Para mayor claridad, el fondo de este componente es azul. Se vería algo así:

Container.jsx
function Alerting({children}) {
return (
<View
style={{backgroundColor: 'blue'}}
onPointerDown={() => alert('Hello World!')}>
{children}
</View>
}

function Container() {
return (
<View style={styles.container}>
<Alerting>
<Widget />
</Alerting>
</View>
);
}

Esto no hace exactamente lo que queremos. Alerting añade una nueva caja de diseño con sus propios límites, separada del Widget hijo. Dependiendo del estilo del elemento que envuelve, esto puede resultar en cambios visuales y funcionales significativos. En este ejemplo, el fondo azul responde a toques con una alerta cuando queremos que solo el cuadro rojo "Hello World" alerte al ser presionado.

antes de display contents

Si lo intentamos nuevamente configurando display: contents en el envoltorio View de Alerting, solo veremos alertas cuando el usuario presione dentro de los límites originales del Widget. Esto ocurre porque Alerting ya no añade su propia caja, pero aún puede observar los eventos de puntero propagados desde Widget.

Container.jsx
function Alerting({children}) {
return (
<View
style={{display: 'contents'}}
onPointerDown={() => alert('Hello World!')}>
{children}
</View>
);
}

// ... function Container ...

resultado con display: contents

Tamaño de caja (boxSizing)

La propiedad boxSizing define cómo se calculan las diversas propiedades de tamaño del elemento (width, height, minWidth, minHeight, etc.). Si boxSizing es border-box, estos tamaños se aplican al borde del elemento. Si es content-box, se aplican al contenido del elemento. El valor predeterminado es border-box, lo cual es diferente al valor predeterminado en la web. La documentación web es una buena fuente si deseas aprender más sobre su funcionamiento.

advertencia

border-box ha sido el valor predeterminado hasta ahora y era el único valor de boxSizing antes de agregar content-box. Cambiar el predeterminado habría roto muchos diseños de forma abrupta. Decidimos mantener border-box como valor predeterminado para garantizar compatibilidad con versiones anteriores.

Para entender la diferencia entre border-box y content-box, observa este ejemplo donde ambos View tienen padding: 20 y borderWidth: 10. Con border-box, el tamaño considera el borde y el relleno; con content-box, solo considera el contenido.

ejemplo de border-box y content-box

Mezcla de colores (CSS mixBlendMode)

La propiedad mixBlendMode controla cómo un elemento mezcla sus colores con otros en su contexto de apilamiento. Consulta la documentación de MDN para ver todas las funciones de mezcla.

Para un control más granular sobre lo que se está mezclando, también añadimos la propiedad isolation. Configurar isolation: isolate en un View forzará a que forme un contexto de apilamiento. Así puedes aplicarlo en un View ancestro para asegurar que un View descendiente con mixBlendMode no se mezcle más allá del aislado View.

Valores de mixBlendMode
  • normal: El elemento se dibuja sobre el fondo sin mezcla.

  • multiply: Multiplica el color fuente por el color destino y lo reemplaza.

  • screen: Multiplica los complementos del fondo y fuente, luego complementa el resultado.

  • overlay: Multiplica o aplica pantalla según el color de fondo.

  • darken: Selecciona el color más oscuro entre fondo y fuente.

  • lighten: Selecciona el color más claro entre fondo y fuente.

  • color-dodge: Aclara el fondo para reflejar el color fuente. Negro no produce cambios.

  • color-burn: Oscurece el fondo para reflejar el color fuente. Blanco no produce cambios.

  • hard-light: Multiplica o aplica pantalla según el color fuente. Efecto similar a un foco intenso.

  • soft-light: Oscurece o aclara según el color fuente. Efecto similar a un foco difuso.

  • difference: Resta el color más oscuro del más claro.

  • exclusion: Similar a Diferencia pero con menos contraste.

  • hue: Crea un color con el tono de la fuente y saturación/luminosidad del fondo.

  • saturation: Crea un color con la saturación de la fuente y tono/luminosidad del fondo.

  • color: Crea un color con el tono y saturación del color fuente, y la luminosidad del color de fondo. Esto preserva los niveles de gris del fondo y es útil para colorear imágenes monocromáticas o aplicar tonos a imágenes en color.

  • luminosity: Crea un color con la luminosidad del color fuente y el tono/saturación del color de fondo. Produce un efecto inverso al modo Color.

modo de mezcla

Propiedades de outline

También introdujimos outlineWidth, outlineStyle, outlineSpread y outlineColor. Estas propiedades funcionan similar a sus equivalentes de border, pero se renderizan alrededor del border box en lugar del padding box. Permiten resaltar elementos dibujando su contorno sin afectar su diseño.

Consulta la documentación de MDN para más detalles.

propiedades de outline

Compatibilidad con Android 15 y soporte para páginas de 16KB

Forzar edge-to-edge en Android 15

Ya realizamos trabajos previos para soportar Android 15. Un cambio notable en Android 15 es el forzado de visualización edge-to-edge al crear apps con targetSdk 35.

Si aún no lo has revisado, consulta nuestra recomendación previa sobre cómo manejarlo, ya que ignorarlo podría dañar tu interfaz.

nota

Si usas react-native-safe-area-context, la biblioteca ya maneja el edge-to-edge forzado.

Soporte para tamaño de página de 16KB en Android

Android 15 introduce soporte para páginas de memoria de 16KB, lo que permite mejoras de rendimiento, pero hace que apps basadas en 4KB sean potencialmente incompatibles en dispositivos futuros; actualmente es una función opcional para probar en dispositivos seleccionados antes de que sea el estándar del SO.

Con la versión 0.77, React Native soporta completamente páginas de 16KB, permitiendo probar y distribuir apps para estos dispositivos.

Consulta el sitio oficial de Android Developers para más detalles sobre soporte de 16KB.

Actualizaciones de la CLI comunitaria y plantillas

CLI comunitaria: Desaprobación de react-native init

Esta versión completa la desaprobación del comando react-native init presentado en React Native 0.75.

Recordatorio: Ya no podrás usar react-native init, sino que deberás:

  • Usar un framework como Expo con su comando dedicado: npx create-expo-app

  • Invocar la Community CLI directamente con npx @react-native-community/cli init

CLI comunitaria: Eliminación de manejadores de teclas "ejecutar en iOS/Android" de Metro

En esta versión eliminamos los atajos de teclado 'a' e 'i' de Metro. Estos invocaban los comandos run-android y run-ios de la CLI comunitaria. Los atajos ofrecían mala experiencia de desarrollo y rara vez se usaban. Además, creemos que los frameworks gestionan mejor las salidas de terminal.

Puedes leer más sobre este cambio en esta publicación dedicada.

Plantilla de la comunidad: Swift como lenguaje de programación para apps iOS

información

Los proyectos que usan Expo no deberían verse afectados por este cambio.

Este cambio nos permite simplificar la plantilla comunitaria al reemplazar tres archivos (main.m, AppDelegate.h y AppDelegate.mm) con un único archivo nuevo: AppDelegate.swift.

Técnicamente, esto es un cambio importante: verás la transición de Objective-C a Swift en el asistente de actualización así:

Asistente de actualización a Swift

No es obligatorio migrar a Swift: la variante Objective-C++ de la plantilla iOS sigue siendo compatible (nota: aún necesitas integrar RCTAppDependencyProvider). Los nuevos proyectos se generarán usando Swift como lenguaje para apps iOS, aunque siempre puedes revertir a Objective-C si lo necesitas.

Limitaciones

Si tu app tiene módulos locales escritos en C++, no podrás registrarlos en Swift como se muestra en esta guía.

Si tu app pertenece a esta categoría, omite la migración del AppDelegate a Swift y mantén Objective-C++.

El núcleo de React Native se desarrolla principalmente en C++ para fomentar la reutilización de código entre iOS, Android y otras plataformas. La interoperabilidad entre Swift y C++ aún no es madura ni estable. Estamos explorando soluciones para cerrar esta brecha y permitir tu migración a Swift.

RCTAppDependencyProvider

React Native 0.77 modifica ligeramente cómo se cargan las dependencias externas. Esta nueva línea en la plantilla comunitaria, si se omite, puede causar problemas en tiempo de ejecución. Asegúrate de incluirla.

Las líneas equivalentes en Objective-C son:

AppDelegate.mm
#import "AppDelegate.h"

#import <React/RCTBundleURLProvider.h>
#import <ReactAppDependencyProvider/RCTAppDependencyProvider.h>


@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.moduleName = @"<Your app Name>";
self.dependencyProvider = [RCTAppDependencyProvider new];
// You can add your custom initial props in the dictionary below.
// They will be passed down to the ViewController used by React Native.
self.initialProps = @{};

return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

// remaining of the AppDelegate

Cambios importantes

Eliminación de la transmisión de console.log() en Metro

Buscamos que cada aspecto de la depuración en React Native sea confiable y coincida con las herramientas modernas de navegadores. Para cumplir este estándar, la retransmisión de logs mediante Metro (obsoleta desde 0.76) se elimina en 0.77.

Esta integración dependía de un enfoque personalizado para comunicarse con el dispositivo. Con este cambio, adoptamos exclusivamente el Protocolo de Herramientas de Desarrollo de Chrome (CDP).

  • Para ver logs JS, usa React Native DevTools y su panel Consola completo - con filtrado de logs, inspección avanzada de objetos, Expresiones en vivo y más.

  • También puedes conectar VS Code como depurador CDP mediante extensiones como Expo Tools y Radon IDE.

    • Nota: Estas integraciones no tienen soporte directo del equipo de React. Estamos trabajando en soporte oficial para VS Code en 2025.
  • Expo mantiene la transmisión de logs en Expo CLI.

Para más detalles, consulta ¿Por qué los logs de JavaScript abandonan Metro?

Otros cambios importantes

General

  • Animación

    • Las animaciones en bucle nativas no envían actualizaciones de estado de React en cada final de ciclo.
  • Maquetación

    • Ahora se considera la position de encabezados fijos en ScrollView.
    • El posicionamiento absoluto ahora tiene un comportamiento más coherente.
  • Módulos JS:

    • Eliminación del módulo ReactFabricInternals
      • Este módulo ya no será accesible
  • Módulos nativos

    • El objeto NativeModules ahora puede usarse para cargar turbomodules en JS
      • Esto mejora la compatibilidad entre módulos nativos y turbomodules nativos
  • Paquetes

    • dev-middleware: Los frameworks deben especificar serverBaseUrl relativo al host del middleware
  • Cambios en la API:

    • Se eliminó el tipo para useConcurrentRoot de AppRegistry, ya que se ignoraba
    • Se eliminó la propiedad refs de la definición TypeScript de NativeMethods
  • Cambios en la experiencia de usuario (UX):

    • Se eliminaron los comandos clave "ejecutar en iOS" y "ejecutar en Android" del servidor de desarrollo

Android

  • Kotlin

    • Esta es la primera versión de React Native que se compila con Kotlin 2.0.21. Puedes leer más sobre los cambios en Kotlin 2.0 en las notas de la versión del lenguaje
  • Cambios en la API:

    • Nulabilidad:
      • Los getters no primitivos en ReadableArray ahora tienen el tipo correcto (opcional)
      • El método ReactHost.createSurface() ahora no acepta valores nulos
    • Renombrados:
      • DevSupportManagerBase.getCurrentContext() pasa a llamarse DevSupportManagerBase.getCurrentReactContext()

Además, varias API se han eliminado o restringido su visibilidad, por lo que ya no son accesibles. Estas API eran internas y no necesarias directamente para desarrolladores de React Native. Puedes encontrar la lista completa a continuación:

List of Removed Android APIs:

The following packages are now internal and can’t be accessed anymore:

  • com.facebook.react.views.progressbar
  • com.facebook.react.views.safeareaview
  • com.facebook.react.modules.accessibilityinfo
  • com.facebook.react.modules.appstate
  • com.facebook.react.modules.clipboard
  • com.facebook.react.modules.devmodule
  • com.facebook.react.modules.reactdevtoolssettings
  • com.facebook.react.views.unimplementedview

The following classes are now either internal or have been removed, so can’t be accessed anymore:

  • BackHandler.removeEventListener
  • BaseViewManagerInterface
  • BindingImpl
  • CompositeReactPackage
  • DebugOverlayTags
  • Method create() from DefaultDevSupportManagerFactory
  • DevToolsReactPerfLogger
  • FabricComponents
  • ImageStoreManager
  • InteropModuleRegistry
  • NativeModulePerfLogger
  • NoopPrinter
  • NotThreadSafeViewHierarchyUpdateDebugListener
  • OkHttpCallUtil
  • PrinterHolder
  • Printer
  • ReactDebugOverlayTags
  • ReactNativeFlipper
  • ReactViewBackgroundManager
  • ReactViewGroup.getBackgroundColor()
  • ReactVirtualTextShadowNode
  • ReactVirtualTextViewManager
  • SimpleSettableFuture
  • SwipeRefreshLayoutManager
  • TaskCompletionSource
  • Parameter jsBundleLoader from DefaultReactHost.getDefaultReactHost()

iOS

  • Cambios en la API:

    • Eliminados:
      • RCTConstants.RCTGetMemoryPressureUnloadLevel
      • partialBatchDidFlush
      • RCTRuntimeExecutor
      • UseNativeViewConfigsInBridgelessMode
        • Reemplazado por un flag de feature adecuado
      • UseTurboModuleInteropForAllTurboModules
        • La capa de interoperabilidad está siempre activa para TMs
    • Modificados:
      • Se reemplazaron los usos de CGColorRef con UIColor
  • RCTAppDelegate ahora requiere usar RCTDependencyProvider para cargar dependencias de terceros

  • CocoaPods establece la versión de C++ para todas las dependencias de terceros para evitar problemas de compilación

React 19?

React 19 was released the 6th of December 2024. At the time, we already cut the branch for React Native 0.77 and we already released three RCs for React Native 0.77. It was too late in the release of React Native 0.77 to introduce React 19 in this release.

React 19 will be shipped in React Native 0.78, and we already cut the branch for this version. You can try it by creating a new app with the command:

npx @react-native-community/cli init YourReact19App --version 0.78.0-rc.0

Agradecimientos

React Native 0.77 contiene más de 1061 commits de 161 colaboradores. ¡Gracias por todo su arduo trabajo!

Agradecemos a los autores adicionales que contribuyeron a documentar características en esta publicación:

Actualización a la versión 0.77

Usa el React Native Upgrade Helper para ver cambios de código entre versiones de React Native en proyectos existentes, además de la documentación de actualización.

Para crear un nuevo proyecto:

npx @react-native-community/cli@latest init MyProject --version latest

Si utilizas Expo, React Native 0.77 será compatible con Expo SDK 52 (las instrucciones para actualizar React Native dentro de tu proyecto de Expo a la versión 0.77.0 estarán disponibles en una publicación de blog de Expo próximamente).

información

0.77 es ahora la última versión estable de React Native y 0.74.x pasa a no ser compatible. Para más información, consulta la política de soporte de React Native. Nuestro objetivo es publicar una actualización final de fin de vida para la versión 0.74 en un futuro próximo.