Saltar al contenido principal

Soporte de Diseño de Derecha a Izquierda para Aplicaciones React Native

· 8 min de lectura
Mengjue (Mandy) Wang
Ingeniera de Software Interna en Facebook
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 →

Tras publicar una aplicación en las tiendas de apps, la internacionalización es el siguiente paso para ampliar tu alcance de audiencia. Más de 20 países y numerosas personas en todo el mundo utilizan idiomas de derecha a izquierda (RTL). Por lo tanto, es fundamental que tu aplicación ofrezca soporte RTL para estos usuarios.

Nos complace anunciar que React Native ha sido mejorado para soportar diseños RTL. Esta funcionalidad ya está disponible en la rama principal de react-native y estará incluida en la próxima versión candidata: v0.33.0-rc.

Esto implicó modificar css-layout, el motor de diseño central utilizado por RN, la implementación principal de RN, así como componentes JS específicos de código abierto para admitir RTL.

Para probar exhaustivamente el soporte RTL en producción, la última versión de la aplicación Facebook Ads Manager (la primera app multiplataforma 100% RN) ya está disponible en árabe y hebreo con diseños RTL tanto para iOS como para Android. Así es como se ve en estos idiomas RTL:

Cambios Generales en RN para Soporte RTL

css-layout ya maneja el concepto de start (inicio) y end (fin) para el diseño. En el flujo izquierda-derecha (LTR), start equivale a left (izquierda) y end a right (derecha). Pero en RTL, start significa right y end significa left. Esto permite que RN utilice los cálculos de start y end para determinar el diseño correcto, incluyendo position, padding y margin.

Además, css-layout hace que la dirección de cada componente herede de su elemento padre. Esto significa que simplemente debemos configurar la dirección del componente raíz como RTL, y toda la aplicación se invertirá automáticamente.

El siguiente diagrama describe los cambios a alto nivel:

Estos incluyen:

Con esta actualización, cuando activas el diseño RTL en tu aplicación:

  • El diseño de cada componente se invertirá horizontalmente

  • Gestos y animaciones adoptarán automáticamente el diseño RTL si usas componentes de código abierto preparados para RTL

  • Puede requerirse un esfuerzo adicional mínimo para que tu aplicación sea completamente compatible con RTL

Preparando una Aplicación para RTL

  1. Para admitir RTL, primero debes agregar los paquetes de idiomas RTL a tu aplicación.

    • Consulta las guías generales para iOS y Android.
  2. Permite el diseño RTL en tu aplicación llamando a la función allowRTL() al inicio del código nativo. Hemos proporcionado esta utilidad para aplicar el diseño RTL solo cuando tu aplicación esté lista. Aquí tienes un ejemplo:

    iOS:

    // in AppDelegate.m
    [[RCTI18nUtil sharedInstance] allowRTL:YES];

    Android:

    // in MainActivity.java
    I18nUtil sharedI18nUtilInstance = I18nUtil.getInstance();
    sharedI18nUtilInstance.allowRTL(context, true);
  3. Para Android, debes agregar android:supportsRtl="true" al elemento <application> en el archivo AndroidManifest.xml.

Ahora, cuando recompiles tu aplicación y cambies el idioma del dispositivo a uno RTL (como árabe o hebreo), el diseño de tu aplicación debería cambiar automáticamente a RTL.

Creación de componentes preparados para RTL

En general, la mayoría de componentes ya están preparados para RTL, por ejemplo:

  • Diseño izquierda-derecha (LTR)
  • Diseño derecha-izquierda (RTL)

Sin embargo, hay varios casos a considerar donde necesitarás el I18nManager. En I18nManager, existe la constante isRTL que indica si el diseño es RTL, permitiéndote realizar ajustes según la dirección del layout.

Iconos con significado direccional

Si tu componente usa iconos o imágenes, se mostrarán igual en diseños LTR y RTL porque RN no voltea las imágenes originales. Debes invertirlos manualmente según la dirección del layout.

  • Diseño izquierda-derecha (LTR)
  • Diseño derecha-izquierda (RTL)

Dos formas de invertir iconos según la dirección:

  • Aplicar estilo transform al componente imagen:

    <Image
    source={...}
    style={{transform: [{scaleX: I18nManager.isRTL ? -1 : 1}]}}
    />
  • O cambiar la fuente de imagen según la dirección:

    let imageSource = require('./back.png');
    if (I18nManager.isRTL) {
    imageSource = require('./forward.png');
    }
    return <Image source={imageSource} />;

Gestos y animaciones

En desarrollo para Android/iOS, al cambiar a RTL los gestos y animaciones se invierten respecto a LTR. Actualmente en RN, estos no tienen soporte a nivel de núcleo pero sí en componentes. Algunos como SwipeableRow y NavigationExperimental ya soportan RTL, pero otros componentes con gestos requerirán ajustes manuales.

Un ejemplo claro de soporte para gestos en RTL es SwipeableRow.

Ejemplo de gestos
// SwipeableRow.js
_isSwipingExcessivelyRightFromClosedPosition(gestureState: Object): boolean {
// ...
const gestureStateDx = IS_RTL ? -gestureState.dx : gestureState.dx;
return (
this._isSwipingRightFromClosed(gestureState) &&
gestureStateDx > RIGHT_SWIPE_THRESHOLD
);
},
Ejemplo de animación
// SwipeableRow.js
_animateBounceBack(duration: number): void {
// ...
const swipeBounceBackDistance = IS_RTL ?
-RIGHT_SWIPE_BOUNCE_BACK_DISTANCE :
RIGHT_SWIPE_BOUNCE_BACK_DISTANCE;
this._animateTo(
-swipeBounceBackDistance,
duration,
this._animateToClosedPositionDuringBounce,
);
},

Mantenimiento de tu aplicación preparada para RTL

Incluso después del lanzamiento inicial de una app compatible con RTL, probablemente necesitarás iterar en nuevas funciones. Para mejorar la eficiencia de desarrollo, I18nManager proporciona la función forceRTL() para pruebas RTL más rápidas sin cambiar el idioma del dispositivo de prueba. Podrías incluir un interruptor simple para esto en tu aplicación. Aquí un ejemplo del caso RTL en RNTester:

<RNTesterBlock title={'Quickly Test RTL Layout'}>
<View style={styles.flexDirectionRow}>
<Text style={styles.switchRowTextView}>forceRTL</Text>
<View style={styles.switchRowSwitchView}>
<Switch
onValueChange={this._onDirectionChange}
style={styles.rightAlignStyle}
value={this.state.isRTL}
/>
</View>
</View>
</RNTesterBlock>;

_onDirectionChange = () => {
I18nManager.forceRTL(!this.state.isRTL);
this.setState({isRTL: !this.state.isRTL});
Alert.alert(
'Reload this page',
'Please reload this page to change the UI direction! ' +
'All examples in this app will be affected. ' +
'Check them out to see what they look like in RTL layout.',
);
};

Al trabajar en una nueva función, puedes alternar fácilmente este botón y recargar la app para ver el diseño RTL. La ventaja es que no necesitarás cambiar la configuración de idioma para probar, aunque algunas alineaciones de texto no cambiarán, como se explica en la siguiente sección. Por lo tanto, siempre es recomendable probar tu app en el idioma RTL antes del lanzamiento.

Limitaciones y Planes Futuros

El soporte RTL debería cubrir la mayoría de la experiencia de usuario en tu app; sin embargo, actualmente existen algunas limitaciones:

  • Los comportamientos de alineación de texto difieren en Android e iOS
    • En iOS, la alineación predeterminada depende del paquete de idioma activo y es consistente en un lado. En Android, la alineación predeterminada depende del idioma del contenido: inglés se alinea a la izquierda y árabe a la derecha.
    • En teoría, esto debería ser consistente entre plataformas, pero algunos usuarios pueden preferir un comportamiento sobre otro. Se necesita más investigación de experiencia de usuario para determinar las mejores prácticas.
  • No existe una "verdadera" izquierda/derecha

    Como se mencionó anteriormente, mapeamos los estilos left/right de JS a start/end. Todo left en código para diseño RTL se convierte en "derecha" en pantalla, y right en código se convierte en "izquierda". Esto es conveniente porque no requiere muchos cambios en tu código, pero significa que no hay forma de especificar "verdadera izquierda" o "verdadera derecha" en el código. En el futuro, podría ser necesario permitir que un componente controle su dirección independientemente del idioma.

  • Hacer el soporte RTL para gestos y animaciones más accesible

    Actualmente, aún se requiere esfuerzo de programación para hacer compatibles gestos y animaciones con RTL. Idealmente, en el futuro se podría simplificar este soporte para desarrolladores.

¡Pruébalo!

Revisa el RTLExample en RNTester para entender mejor el soporte RTL, y ¡cuéntanos cómo te funciona!

Finalmente, ¡gracias por leer! Esperamos que el soporte RTL en React Native te ayude a expandir tus aplicaciones para audiencias internacionales.

Resumen del Meetup de San Francisco

· 9 min de lectura
Héctor Ramos
Héctor Ramos
Former Developer Advocate @ Facebook
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 →

La semana pasada tuve la oportunidad de asistir al Meetup de React Native en la oficina de Zynga en San Francisco. Con alrededor de 200 asistentes, fue un excelente lugar para conocer a otros desarrolladores cercanos que también están interesados en React Native.

Estaba especialmente interesado en aprender más sobre cómo usan React y React Native en empresas como Zynga, Netflix y Airbnb. La agenda de la noche sería la siguiente:

  • Prototipado Rápido en React

  • Diseño de APIs para React Native

  • Cerrando la Brecha: Usando React Native en Bases de Código Existentes

Pero primero, el evento comenzó con una breve introducción y un resumen de noticias recientes:

Si uno de estos meetups se realiza cerca de ti, ¡te recomiendo encarecidamente asistir!

Prototipado Rápido en React en Zynga

Tras la ronda de noticias, Zynga, nuestros anfitriones de la noche, hizo una breve presentación. Abhishek Chadha habló sobre cómo usan React para prototipar rápidamente nuevas experiencias en móviles, mostrando un prototipo rápido de una aplicación similar a Draw Something. Utilizan un enfoque similar a React Native, proporcionando acceso a APIs nativas mediante un puente. Esto se demostró cuando Abhishek usó la cámara del dispositivo para tomar una foto de la audiencia y luego dibujó un sombrero en la cabeza de alguien.

Diseño de APIs para React Native en Netflix

A continuación, la primera charla destacada de la noche. Clarence Leung, Ingeniero de Software Senior en Netflix, presentó su charla sobre Diseño de APIs para React Native. Primero señaló los dos tipos principales de bibliotecas en las que se puede trabajar: componentes como barras de pestañas y selectores de fecha, y bibliotecas que brindan acceso a servicios nativos como el rollo de cámara o pagos in-app. Hay dos enfoques posibles al construir una biblioteca para usar en React Native:

  • Proporcionar componentes específicos por plataforma

  • Una biblioteca multiplataforma con una API similar para Android e iOS

Cada enfoque tiene sus propias consideraciones, y depende de ti determinar cuál funciona mejor para tus necesidades.

Enfoque #1

Como ejemplo de componentes específicos por plataforma, Clarence mencionó DatePickerIOS y DatePickerAndroid del núcleo de React Native. En iOS, los selectores de fecha se renderizan como parte de la UI y pueden integrarse fácilmente en una vista existente, mientras que en Android se presentan modalmente. Tiene sentido proporcionar componentes separados en este caso.

Enfoque #2

Los selectores de fotos, por otro lado, se manejan de manera similar en Android e iOS. Existen ligeras diferencias —Android no agrupa las fotos en carpetas como iOS lo hace con los Selfies, por ejemplo— pero estas se resuelven fácilmente usando sentencias if y el componente Platform.

Independientemente del enfoque que elijas, es recomendable minimizar la superficie de la API y construir bibliotecas específicas para cada aplicación. Por ejemplo, el sistema de Compras In-App de iOS soporta transacciones únicas, consumibles y suscripciones renovables. Si tu aplicación solo necesita manejar compras consumibles, puedes prescindir del soporte para suscripciones en tu biblioteca multiplataforma.

Al final de la charla de Clarence hubo una breve sesión de preguntas. Un dato interesante que surgió fue que alrededor del 80% del código React Native escrito para estas bibliotecas en Netflix se comparte entre Android e iOS.

Cerrando la brecha: Uso de React Native en bases de código existentes

La charla final fue impartida por Leland Richardson de Airbnb, enfocándose en el uso de React Native en bases de código existentes. Si bien es sencillo crear una nueva app desde cero con React Native, me interesaba especialmente conocer la experiencia de Airbnb al adoptarlo en sus aplicaciones nativas ya establecidas.

Leland comenzó diferenciando aplicaciones greenfield (proyectos nuevos sin restricciones previas) versus brownfield (proyectos que deben integrarse con códigobase existente, procesos de desarrollo y necesidades de equipos establecidos).

En proyectos greenfield, la CLI de React Native configura un único repositorio para Android e iOS que funciona inmediatamente. El primer desafío para Airbnb fue que sus aplicaciones móviles tenían repositorios separados. Las empresas con múltiples repositorios enfrentan obstáculos adicionales al adoptar React Native.

Para solucionarlo, Airbnb creó un nuevo repositorio para el código React Native. Sus servidores de CI replicaban los repositorios nativos en este nuevo espacio. Tras ejecutar pruebas y construir el bundle, los artefactos se sincronizaban con los repositorios originales. Esto permitía:

  • Ingenieros móviles trabajar sin instalar npm o ejecutar el packager
  • Especialistas en React Native enfocarse en su código sin preocuparse por sincronización entre plataformas

Este enfoque tenía desventajas, principalmente la imposibilidad de implementar actualizaciones atómicas. Cambios que requerían modificar código nativo y JavaScript necesitaban tres pull requests separados, que debían integrarse con extrema precisión. Para evitar conflictos, el CI cancelaba la sincronización si la rama master cambiaba durante la construcción, causando demoras en periodos de alta actividad (como lanzamientos de versiones).

Airbnb migró posteriormente a un enfoque de mono-repo. Afortunadamente, esta transición ya estaba considerada, y al ver los beneficios de React Native, los equipos de Android e iOS aceleraron voluntariamente este cambio.

Esto resolvió la mayoría de los problemas del enfoque multi-repo, aunque Leland destacó que incrementa la carga en los servidores de control de versiones, algo que podría afectar a empresas más pequeñas.

El problema de la navegación

La segunda parte de la charla abordó un tema crucial: la navegación en React Native. Leland mencionó la proliferación de bibliotecas de navegación (oficiales y de terceros), destacando que NavigationExperimental parecía prometedora pero finalmente no se adaptó a sus necesidades específicas.

De hecho, ninguna de las bibliotecas de navegación existentes parece funcionar bien para aplicaciones brownfield. Una aplicación brownfield requiere que el estado de navegación sea completamente controlado por la aplicación nativa. Por ejemplo, si la sesión de un usuario expira mientras se muestra una vista de React Native, la aplicación nativa debe poder tomar el control y mostrar una pantalla de inicio de sesión según sea necesario.

Airbnb también quería evitar reemplazar las barras de navegación nativas con versiones JavaScript durante la transición, ya que el efecto podría resultar discordante. Inicialmente se limitaron a vistas presentadas modalmente, pero esto obviamente planteaba un problema al adoptar React Native de manera más amplia en sus aplicaciones.

Decidieron que necesitaban su propia biblioteca. La biblioteca se llama airbnb-navigation. Aún no se ha liberado como código abierto porque está fuertemente vinculada al código base de Airbnb, pero es algo que les gustaría publicar antes de fin de año.

No entraré en muchos detalles sobre la API de la biblioteca, pero estos son algunos de los puntos clave:

  • Se deben pre-registrar las escenas con anticipación

  • Cada escena se muestra dentro de su propio RCTRootView. Se presentan de forma nativa en cada plataforma (por ejemplo, se usan UINavigationControllers en iOS).

  • El ScrollView principal en una escena debe envolverse en un componente ScrollScene. Esto permite aprovechar comportamientos nativos como tocar la barra de estado para desplazarse al inicio en iOS.

  • Las transiciones entre escenas se manejan de forma nativa, sin preocupaciones de rendimiento.

  • El botón Atrás de Android tiene soporte automático.

  • Pueden aprovechar el estilo de barra de navegación basado en View Controller mediante un componente Navigator.Config sin UI.

También hay algunas consideraciones a tener en cuenta:

  • La barra de navegación no se personaliza fácilmente en JavaScript, ya que es un componente nativo. Esto es intencional, ya que usar barras de navegación nativas es un requisito fundamental para este tipo de biblioteca.

  • Los ScreenProps deben serializarse/deserializarse cuando se envían a través del puente, por lo que debe tenerse cuidado al enviar demasiados datos aquí.

  • El estado de navegación es controlado por la aplicación nativa (también un requisito fundamental), por lo que herramientas como Redux no pueden manipular el estado de navegación.

La charla de Leland también incluyó una sesión de preguntas y respuestas. En general, Airbnb está satisfecha con React Native. Están interesados en usar Code Push para solucionar problemas sin pasar por la App Store, y sus ingenieros adoran Live Reload, ya que no necesitan reconstruir la aplicación nativa tras cada cambio menor.

Palabras de cierre

El evento finalizó con noticias adicionales sobre React Native:

Los meetups brindan una excelente oportunidad para conocer y aprender de otros desarrolladores de la comunidad. Espero asistir a más meetups de React Native en el futuro. Si asistes a alguno, ¡búscame y cuéntame cómo podemos mejorar React Native para ti!

Hacia una mejor documentación

· 5 min de lectura
Kevin Lacker
Engineering Manager en Facebook
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 →

Parte de una gran experiencia para desarrolladores es contar con una excelente documentación. Crear buenos documentos requiere mucho: la documentación ideal debe ser concisa, útil, precisa, completa y atractiva. Recientemente hemos trabajado arduamente para mejorar la documentación basándonos en sus comentarios, y queremos compartir algunas de las mejoras que hemos implementado.

Ejemplos integrados

Cuando aprendes una nueva biblioteca, lenguaje de programación o framework, hay un hermoso momento en que escribes un poco de código, lo pruebas, ves si funciona... y realmente funciona. Has creado algo real. Queríamos llevar esa experiencia visceral directamente a nuestra documentación. Así:

import React, { Component } from 'react';
import { AppRegistry, Text, View } from 'react-native';

class ScratchPad extends Component {
render() {
return (
<View style={{flex: 1}}>
<Text style={{fontSize: 30, flex: 1, textAlign: 'center'}}>
Isn't this cool?
</Text>
<Text style={{fontSize: 100, flex: 1, textAlign: 'center'}}>
👍
</Text>
</View>
);
}
}

AppRegistry.registerComponent('ScratchPad', () => ScratchPad);

Creemos que estos ejemplos integrados, que usan el módulo react-native-web-player con ayuda de Devin Abbott, son una excelente forma de aprender los fundamentos de React Native. Hemos actualizado nuestro tutorial para nuevos desarrolladores de React Native para usarlos siempre que sea posible. Échale un vistazo: si alguna vez has sentido curiosidad por ver qué pasaría si modificas solo un fragmento del código de ejemplo, esta es una forma genial de experimentar. Además, si estás construyendo herramientas para desarrolladores y quieres mostrar muestras en vivo de React Native en tu sitio, react-native-web-player puede simplificarlo.

El motor central de simulación lo proporciona el proyecto react-native-web de Nicolas Gallagher, que permite mostrar componentes de React Native como Text y View en la web. Explora react-native-web si te interesa crear experiencias móviles y web que compartan gran parte de la base de código.

Guías mejoradas

En algunas partes de React Native existen múltiples formas de hacer las cosas, y hemos recibido comentarios de que podríamos ofrecer mejores orientaciones.

Tenemos una nueva guía de Navegación que compara los diferentes enfoques y recomienda qué deberías usar: Navigator, NavigatorIOS, NavigationExperimental. A mediano plazo, estamos trabajando para mejorar y consolidar esas interfaces. A corto plazo, esperamos que esta guía mejorada facilite tu trabajo.

También tenemos una nueva guía sobre manejo de toques que explica conceptos básicos para crear interfaces similares a botones, y un resumen breve de las diferentes formas de manejar eventos táctiles.

Otra área en la que trabajamos es Flexbox. Esto incluye tutoriales sobre cómo manejar diseño con Flexbox y cómo controlar el tamaño de componentes. También incluye una lista poco glamorosa pero útil de todas las props que controlan el diseño en React Native.

Comenzando

Al comenzar a configurar un entorno de desarrollo de React Native en tu máquina, necesitas instalar y configurar varios elementos. Es difícil que la instalación sea una experiencia divertida y emocionante, pero al menos podemos hacerla lo más rápida e indolora posible.

Creamos un nuevo flujo de Comenzando que te permite seleccionar tu sistema operativo de desarrollo y tu sistema operativo móvil desde el principio, proporcionando un lugar conciso con todas las instrucciones de configuración. También revisamos el proceso de instalación para garantizar que todo funcione y que cada punto de decisión tenga una recomendación clara. Tras probarlo con nuestros inocentes compañeros, estamos seguros de que es una mejora.

También trabajamos en la guía para integrar React Native en aplicaciones existentes. Muchas de las aplicaciones más grandes que usan React Native, como la propia aplicación de Facebook, construyen parte de la app con React Native y otra parte con herramientas de desarrollo convencionales. Esperamos que esta guía facilite que más personas puedan crear aplicaciones de esta manera.

Necesitamos tu ayuda

Tu retroalimentación nos indica en qué debemos enfocarnos. Sé que algunas personas leerán esta publicación y pensarán: "¿Mejor documentación? Pfff. ¡La documentación de X sigue siendo deficiente!". Eso es genial, necesitamos esa energía. La mejor manera de darnos feedback depende del tipo de comentario.

Si encuentras un error en la documentación, como descripciones inexactas o código que no funciona, crea un issue. Etiquétalo como "Documentation" para que sea más fácil dirigirlo a las personas adecuadas.

Si no hay un error específico, pero algo en la documentación es fundamentalmente confuso, no es adecuado para un issue de GitHub. En su lugar, publica en Canny sobre el área de la documentación que necesita mejoras. Esto nos ayuda a priorizar cuando realizamos trabajos más generales como la redacción de guías.

¡Gracias por leer hasta aquí y gracias por usar React Native!

React Native: Un año en retrospectiva

· 2 min de lectura
Martin Konicek
Ingeniero de Software en Facebook
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 →

Ha pasado un año desde que hicimos open-source de React Native. Lo que comenzó como una idea con un puñado de ingenieros es ahora un framework utilizado por equipos de producto en Facebook y más allá. Hoy en F8 anunciamos que Microsoft está llevando React Native al ecosistema Windows, permitiendo a los desarrolladores crear aplicaciones React Native para PC, teléfonos y Xbox con Windows. También proporcionará herramientas y servicios de código abierto como una extensión de React Native para Visual Studio Code y CodePush para ayudar a los desarrolladores a crear aplicaciones React Native en la plataforma Windows. Además, Samsung está desarrollando React Native para su plataforma híbrida, lo que permitirá a los desarrolladores crear aplicaciones para millones de SmartTVs, dispositivos móviles y wearables. También lanzamos el Facebook SDK para React Native, que facilita a los desarrolladores incorporar funciones sociales de Facebook como Login, Sharing, App Analytics y Graph APIs en sus aplicaciones. En un año, React Native ha cambiado la forma en que los desarrolladores construyen aplicaciones en todas las plataformas principales.

Ha sido un viaje épico, pero apenas estamos comenzando. Aquí repasamos cómo React Native ha crecido y evolucionado desde que lo hicimos open-source hace un año, algunos desafíos que enfrentamos en el camino y lo que esperamos de cara al futuro.

Este es un extracto. Lee el resto de la publicación en Facebook Code.

Profundizando en el rendimiento de React Native

· 2 min de lectura
Pieter De Baets
Ingeniero de Software en Facebook
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 →

React Native te permite crear aplicaciones para Android e iOS usando JavaScript con el modelo de programación declarativa de React y Relay. Esto genera código más conciso y fácil de entender; iteración rápida sin ciclos de compilación; y compartir código fácilmente entre múltiples plataformas. Puedes lanzar más rápido y enfocarte en los detalles que realmente importan, haciendo que tu aplicación luzca y funcione de maravilla. Optimizar el rendimiento es parte fundamental de esto. Esta es la historia de cómo duplicamos la velocidad de inicio de apps con React Native.

¿Por qué la prisa?

Con una aplicación que funciona más rápido, el contenido carga rápidamente, lo que significa que los usuarios tienen más tiempo para interactuar con él, y las animaciones fluidas hacen que la aplicación sea agradable de usar. En mercados emergentes, donde predominan teléfonos de clase 2011 en redes 2G, enfocarse en el rendimiento puede marcar la diferencia entre una aplicación utilizable y una que no lo es.

Desde que lanzamos React Native en iOS y en Android, hemos mejorado el rendimiento del desplazamiento en listas, eficiencia de memoria, capacidad de respuesta de la UI y tiempo de inicio de aplicaciones. El inicio establece la primera impresión de una app y tensiona todas las partes del framework, por lo que es el problema más gratificante y desafiante de abordar.

Este es un extracto. Lee el resto de la publicación en Facebook Code.

Presentamos Hot Reloading

· 9 min de lectura
Martín Bigio
Ingeniero de Software en Instagram
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 →

El objetivo de React Native es brindarte la mejor experiencia de desarrollo posible. Un aspecto crucial es el tiempo transcurrido entre guardar un archivo y poder ver los cambios. Nuestra meta es que este ciclo de retroalimentación sea inferior a 1 segundo, incluso a medida que tu aplicación crece.

Nos acercamos a este ideal mediante tres características principales:

  • Usar JavaScript, ya que este lenguaje no tiene tiempos largos de ciclo de compilación.

  • Implementar una herramienta llamada Packager que transforma archivos es6/flow/jsx en JavaScript estándar comprensible para la máquina virtual. Fue diseñado como servidor que mantiene estados intermedios en memoria para cambios incrementales rápidos y utiliza múltiples núcleos.

  • Crear una función llamada Live Reload que recarga la aplicación al guardar.

En este punto, el cuello de botella para desarrolladores ya no es el tiempo de recarga, sino la pérdida del estado de la aplicación. Un escenario común es trabajar en una función que está a varias pantallas de la de inicio. Cada vez que recargas, debes recorrer la misma ruta repetidamente para volver a tu función, alargando el ciclo a varios segundos.

Hot Reloading

La idea detrás de Hot Reloading es mantener la aplicación en ejecución e inyectar nuevas versiones de los archivos editados durante el tiempo de ejecución. Así no pierdes ningún estado, algo especialmente útil cuando ajustas la interfaz de usuario.

Un video vale más que mil palabras. Observa la diferencia entre Live Reload (actual) y Hot Reload (nuevo).

Si observas detenidamente, notarás que es posible recuperarse de un error (red box) e importar módulos que antes no existían sin necesidad de recarga completa.

Advertencia: como JavaScript es un lenguaje con estado, Hot Reloading no puede implementarse perfectamente. En la práctica, descubrimos que la configuración actual funciona bien para la mayoría de casos de uso comunes, y siempre está disponible la recarga completa si algo falla.

Hot Reloading está disponible desde la versión 0.22. Puedes activarlo así:

  • Abre el menú de desarrollo

  • Toca "Enable Hot Reloading"

Implementación en pocas palabras

Ahora que vimos por qué lo necesitamos y cómo usarlo, viene la parte divertida: cómo funciona realmente.

Hot Reloading se basa en Hot Module Replacement (HMR), una función introducida primero por webpack que implementamos en React Native Packager. HMR hace que Packager detecte cambios en archivos y envíe actualizaciones HMR a un pequeño entorno de ejecución HMR incluido en la app.

En esencia, la actualización HMR contiene el nuevo código de los módulos JS modificados. Cuando el entorno de ejecución los recibe, reemplaza el código antiguo por el nuevo:

La actualización HMR contiene algo más que solo el código del módulo porque reemplazarlo no basta para que el entorno de ejecución detecte cambios. El problema es que el sistema de módulos podría tener en caché las exportaciones del módulo a actualizar. Por ejemplo, imagina una app con estos dos módulos:

// log.js
function log(message) {
const time = require('./time');
console.log(`[${time()}] ${message}`);
}

module.exports = log;
// time.js
function time() {
return new Date().getTime();
}

module.exports = time;

El módulo log imprime el mensaje recibido incluyendo la fecha actual proporcionada por el módulo time.

Al agrupar la app, React Native registra cada módulo mediante la función __d. Para esta app, entre muchas definiciones __d, habrá una para log:

__d('log', function() {
... // module's code
});

Esta invocación envuelve el código de cada módulo en una función anónima, comúnmente llamada función fábrica. El sistema de módulos mantiene un registro de la función fábrica de cada módulo, si ya ha sido ejecutada y el resultado de dicha ejecución (exportaciones). Cuando un módulo es requerido, el sistema proporciona las exportaciones en caché o ejecuta la función fábrica por primera vez guardando el resultado.

Imagina que inicias tu aplicación y requieres log. En este punto, ni log ni las funciones fábrica de time han sido ejecutadas, por lo que no hay exportaciones en caché. Luego, el usuario modifica time para retornar la fecha en formato MM/DD:

// time.js
function bar() {
const date = new Date();
return `${date.getMonth() + 1}/${date.getDate()}`;
}

module.exports = bar;

El Packager enviará el nuevo código de time al runtime (paso 1), y cuando log sea requerido eventualmente, la función exportada se ejecutará incorporando los cambios de time (paso 2):

Ahora supongamos que el código de log requiere time como una dependencia de primer nivel:

const time = require('./time'); // top level require

// log.js
function log(message) {
console.log(`[${time()}] ${message}`);
}

module.exports = log;

Cuando se requiere log, el runtime almacenará en caché sus exportaciones y las de time (paso 1). Si luego modificas time, el proceso HMR no puede finalizar simplemente reemplazando el código de time. Si lo hiciera, cuando se ejecute log, usaría la copia en caché de time (código antiguo).

Para que log incorpore los cambios de time, debemos limpiar sus exportaciones en caché porque uno de sus módulos dependientes fue reemplazado en caliente (paso 3). Finalmente, cuando log sea requerido nuevamente, su función fábrica se ejecutará requiriendo time y obteniendo su nuevo código.

API de HMR

HMR en React Native extiende el sistema de módulos mediante el objeto hot. Esta API está basada en la de webpack. El objeto hot expone una función accept que permite definir un callback ejecutado cuando el módulo necesita ser reemplazado en caliente. Por ejemplo, si modificamos el código de time así, veremos "time changed" en consola cada vez que guardemos:

// time.js
function time() {
... // new code
}

module.hot.accept(() => {
console.log('time changed');
});

module.exports = time;

Nota: Solo en casos raros necesitarás usar esta API manualmente. Hot Reloading debería funcionar automáticamente en la mayoría de los casos comunes.

Runtime de HMR

Como vimos antes, a veces no basta con aceptar la actualización HMR porque un módulo que usa el componente reemplazado podría ya haberse ejecutado con sus importaciones en caché. Por ejemplo, supongamos que la app de películas tiene un MovieRouter de primer nivel que depende de las vistas MovieSearch y MovieScreen, las cuales dependen de los módulos log y time:

Si el usuario accede a la vista de búsqueda pero no a otras, todos los módulos excepto MovieScreen tendrían exportaciones en caché. Al cambiar time, el runtime deberá limpiar las exportaciones de log para incorporar los cambios de time. El proceso no termina ahí: el runtime repetirá esto recursivamente hasta que todos los padres hayan sido aceptados. Buscará módulos que dependan de log e intentará aceptarlos. Para MovieScreen puede omitirse (no se ha requerido). Para MovieSearch, limpiará sus exportaciones y procesará sus padres recursivamente. Finalmente, hará lo mismo con MovieRouter y terminará, ya que ningún módulo depende de él.

Para recorrer el árbol de dependencias, el runtime recibe el árbol de dependencias inversas del Packager en la actualización HMR. Para este ejemplo recibirá un objeto JSON como:

{
modules: [
{
name: 'time',
code: /* time's new code */
}
],
inverseDependencies: {
MovieRouter: [],
MovieScreen: ['MovieRouter'],
MovieSearch: ['MovieRouter'],
log: ['MovieScreen', 'MovieSearch'],
time: ['log'],
}
}

Componentes de React

Los componentes de React son un poco más difíciles de hacer funcionar con Hot Reloading. El problema es que no podemos simplemente reemplazar el código antiguo por el nuevo porque perderíamos el estado del componente. Para aplicaciones web de React, Dan Abramov implementó una transformación de Babel que usa la API HMR de webpack para resolver este problema. En resumen, su solución funciona creando un proxy para cada componente React durante el tiempo de transformación. Los proxies mantienen el estado del componente y delegan los métodos del ciclo de vida en los componentes reales, que son los que recargamos en caliente:

Además de crear el componente proxy, la transformación también define la función accept con un fragmento de código para forzar a React a volver a renderizar el componente. Así podemos recargar en caliente el código de renderizado sin perder el estado de la aplicación.

El transformador predeterminado que viene con React Native usa babel-preset-react-native, que está configurado para usar react-transform de la misma manera que lo harías en un proyecto web de React que utilice webpack.

Tiendas Redux

Para habilitar Hot Reloading en tiendas Redux, solo necesitarás usar la API HMR de manera similar a como lo harías en un proyecto web con webpack:

// configureStore.js
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import reducer from '../reducers';

export default function configureStore(initialState) {
const store = createStore(
reducer,
initialState,
applyMiddleware(thunk),
);

if (module.hot) {
module.hot.accept(() => {
const nextRootReducer = require('../reducers/index').default;
store.replaceReducer(nextRootReducer);
});
}

return store;
};

Cuando cambias un reducer, el código para aceptar ese reducer se enviará al cliente. Entonces el cliente se dará cuenta de que el reducer no sabe cómo aceptarse a sí mismo, por lo que buscará todos los módulos que lo referencian e intentará aceptarlos. Eventualmente, el flujo llegará a la tienda única, el módulo configureStore, que aceptará la actualización HMR.

Conclusión

Si estás interesado en ayudar a mejorar el hot reloading, te animo a leer la publicación de Dan Abramov sobre el futuro del hot reloading y a contribuir. Por ejemplo, Johny Days va a hacerlo funcionar con múltiples clientes conectados. Dependemos de todos ustedes para mantener y mejorar esta función.

Con React Native, tenemos la oportunidad de repensar cómo construimos aplicaciones para ofrecer una gran experiencia de desarrollo. El hot reloading es solo una pieza del rompecabezas, ¿qué otras soluciones creativas podemos implementar para mejorarla?

Haciendo accesibles las aplicaciones de React Native

· 2 min de lectura
Georgiy Kassabli
Ingeniero de Software en Facebook
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 →

Con el reciente lanzamiento de React para web y React Native para móviles, hemos proporcionado un nuevo marco de trabajo frontend para que los desarrolladores construyan productos. Un aspecto clave al crear un producto robusto es garantizar que cualquiera pueda usarlo, incluyendo personas con pérdida de visión u otras discapacidades. La API de Accesibilidad para React y React Native te permite hacer que cualquier experiencia basada en React sea utilizable por alguien que podría usar tecnología asistiva, como un lector de pantalla para personas ciegas o con baja visión.

En esta publicación, nos centraremos en aplicaciones de React Native. Hemos diseñado la API de Accesibilidad de React para que tenga una apariencia y funcionamiento similar a las APIs de Android e iOS. Si has desarrollado aplicaciones accesibles para Android, iOS o la web antes, deberías sentirte familiarizado con el marco y la nomenclatura de la React AX API. Por ejemplo, puedes hacer que un elemento de UI sea accesible (y por tanto expuesto a tecnología asistiva) y usar accessibilityLabel para proporcionar una descripción textual del elemento:

<View accessible={true} accessibilityLabel=”This is simple view”>

Exploremos una aplicación ligeramente más compleja de la React AX API mediante un producto propio de Facebook impulsado por React: la app Ads Manager.

Este es un extracto. Lee el resto de la publicación en Facebook Code.

React Native para Android: Cómo construimos la primera aplicación React Native multiplataforma

· 2 min de lectura
Ingeniero de Software en Facebook
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 →

A principios de este año, presentamos React Native para iOS. React Native lleva al mundo móvil lo que los desarrolladores ya conocen de React en la web —componentes de UI declarativos e independientes y ciclos de desarrollo rápidos— manteniendo la velocidad, fidelidad y experiencia de aplicaciones nativas. Hoy nos complace anunciar React Native para Android.

En Facebook llevamos usando React Native en producción más de un año. Casi exactamente hace un año, nuestro equipo comenzó a desarrollar la aplicación Ads Manager. Nuestro objetivo era crear una nueva aplicación que permitiera a los millones de anunciantes en Facebook gestionar sus cuentas y crear anuncios desde cualquier lugar. El resultado fue no solo la primera aplicación completamente React Native de Facebook, sino también la primera multiplataforma. En esta publicación, compartiremos cómo construimos esta aplicación, cómo React Native aceleró nuestro desarrollo y las lecciones aprendidas.

Este es un extracto. Lee la publicación completa en Facebook Code.

React Native: Llevando técnicas web modernas a móviles

· 3 min de lectura
Tom Occhino
Gerente de Ingeniería en Facebook
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 →

Presentamos React al mundo hace dos años, y desde entonces ha experimentado un crecimiento impresionante, tanto dentro como fuera de Facebook. Hoy en día, aunque nadie está obligado a usarlo, los nuevos proyectos web en Facebook comúnmente se construyen usando React de una forma u otra, y está siendo ampliamente adoptado en la industria. Los ingenieros eligen usar React todos los días porque les permite dedicar más tiempo a centrarse en sus productos y menos tiempo luchando con su framework. Sin embargo, no fue hasta que llevábamos un tiempo construyendo con React que empezamos a entender qué lo hace tan poderoso.

React nos obliga a descomponer nuestras aplicaciones en componentes discretos, cada uno representando una única vista. Estos componentes facilitan la iteración en nuestros productos, ya que no necesitamos mantener todo el sistema en nuestra cabeza para hacer cambios en una parte del mismo. Sin embargo, lo más importante es que React envuelve la API mutativa e imperativa del DOM con una declarativa, lo que eleva el nivel de abstracción y simplifica el modelo de programación. Lo que hemos descubierto es que cuando construimos con React, nuestro código es mucho más predecible. Esta previsibilidad hace que podamos iterar más rápidamente con confianza, y nuestras aplicaciones son mucho más confiables como resultado. Además, no solo es más fácil escalar nuestras aplicaciones cuando están construidas con React, sino que también hemos descubierto que es más fácil escalar el tamaño de nuestros equipos.

Junto con el ciclo de iteración rápida de la web, hemos podido construir algunos productos increíbles con React, incluyendo muchos componentes de Facebook.com. Además, hemos construido frameworks asombrosos en JavaScript sobre React, como Relay, que nos permite simplificar enormemente la obtención de datos a gran escala. Por supuesto, la web es solo una parte de la historia. Facebook también tiene aplicaciones ampliamente utilizadas para Android e iOS, que están construidas sobre pilas tecnológicas propietarias y disjuntas. Tener que construir nuestras aplicaciones sobre múltiples plataformas ha bifurcado nuestra organización de ingeniería, pero eso es solo una de las cosas que hace difícil el desarrollo de aplicaciones móviles nativas.

Este es un extracto. Lee el resto de la publicación en Facebook Code.