Saltar al contenido

Comprensión de la arquitectura nativa de React | Vinova

React Native es un excelente punto de entrada al desarrollo de aplicaciones para un desarrollador web, especialmente con las experiencias de React.

Sin embargo, eso no significa que React Native sea simple. Puede escribir aplicaciones con su lenguaje familiar, JavaScript, pero ciertamente requiere una comprensión general de las plataformas iOS y Android. Este artículo es un resumen de mi proceso de aprendizaje sobre la arquitectura React Native y el ecosistema desde el punto de vista del desarrollador web.

Los entornos de ejecución

React se ejecuta en el entorno de ejecución de JavaScript. Para la web, es un navegador web. Hay un solo hilo de JavaScript y utiliza API web implementadas de forma nativa en el navegador.

Es importante comprender cómo funcionan las devoluciones de llamada entre el hilo JS principal y las API web, especialmente cuando se utilizan funciones asincrónicas. Esta interacción entre el motor JavaScript y las API nativas también es vital para comprender cómo se comporta React Native en su entorno.

Hilos en React Native

Hay tres subprocesos clave en el entorno de ejecución de React Native, el subproceso de JavaScript, el subproceso principal nativo y el subproceso de fondo para manejar Shadow Node.

En la arquitectura actual, la comunicación entre estos subprocesos ocurre a través de la biblioteca llamada “puente”.

El equipo de React Native está trabajando activamente en la actualización principal de la arquitectura y este artículo ofrece una excelente descripción general de por qué y cómo se necesita el cambio.

No entro en detalles, pero la comprensión básica de la arquitectura actual y futura ayuda a modelar su aplicación, especialmente para separar las preocupaciones.

Reaccionar y reaccionar nativo

Como puede ver arriba, React Native cubre un área significativamente más amplia que React en sí.

React for the web parece bastante intuitivo ya que el concepto clave, el DOM virtual, implica la representación de dom HTML de los navegadores. Pero, de hecho, el DOM virtual no está vinculado al DOM HTML (Modelo de objeto de documento). El DOM virtual en React es más un concepto de programación o un patrón que una tecnología específica.

Proporciona una abstracción para la interfaz de usuario declarativa. La representación virtual de una IU se guarda en la memoria y se sincroniza con las bibliotecas de IU externas. Este proceso se llama.

Puede leer una buena explicación de la arquitectura React Fiber aquí.

Reconciliación versus renderizado

El DOM es solo uno de los entornos de renderizado en los que React puede renderizar, los otros objetivos principales son las vistas nativas de iOS y Android a través de React Native. (Esta es la razón por la que “DOM virtual” es un nombre poco apropiado).

La razón por la que puede admitir tantos objetivos es porque React está diseñado para que la reconciliación y el renderizado sean fases separadas. El reconciliador hace el trabajo de calcular qué partes de un árbol han cambiado; el renderizador luego usa esa información para actualizar realmente la aplicación renderizada.
Esta separación significa que React DOM y React Native pueden usar sus propios renderizadores mientras comparten el mismo reconciliador, proporcionado por React core.
La fibra vuelve a implementar el reconciliador. No se ocupa principalmente de la renderización, aunque los renderizadores deberán cambiar para admitir (y aprovechar) la nueva arquitectura.

Reaccionar componentes nativos y reaccionar navegación

React Native proporciona su propia capa de abstracción de la interfaz de usuario en las plataformas iOS y Android. React Native core y los componentes nativos invocan las vistas nativas para que pueda escribir la interfaz de usuario de la aplicación del teléfono inteligente con JavaScript, en lugar de Kotlin / Java o Swift / Objective-C.

Componentes principales y componentes nativos Los componentes nativos cubren elementos de IU nativos completos, pero aún necesita escribir mucho código para simular la experiencia del usuario nativo, como la navegación por pestañas. Ahí es donde entra React Navigation.

React Navigation es una biblioteca de JavaScript pura que no incluye ningún código nativo. Se basa en otras bibliotecas nativas como Reanimated, Gesture Handler y Screens para implementar los patrones de navegación de aplicaciones comunes.

Proporciona las mejores prácticas sobre cómo estructurar y navegar por las pantallas de la aplicación, que es una de las partes más confusas cuando se tiene experiencia en desarrollo web.
Mi consejo es ceñirse a los patrones de navegación básicos hasta que esté seguro y pueda implementar sus navegadores personalizados en la parte superior de React Navigation una vez que tenga buenas vistas generales. También preferiría colocar navegadores y pantallas en los directorios dedicados para separarlos claramente de los otros componentes.

Pensando en reaccionar

A pesar de la diferencia en las implementaciones de la interfaz de usuario, el proceso de pensamiento para crear una nueva aplicación sigue siendo el mismo que el de “pensar en reaccionar”.

  • Empiece con un simulacro
  • Divida la interfaz de usuario en una jerarquía de componentes
  • Cree una versión estática en React
  • Identificar la representación mínima (pero completa) del estado de la interfaz de usuario
  • Identifique dónde debería vivir su estado
  • Agregar flujo de datos inverso

Ganchos y componente funcional

React 16.8.0 introdujo Hooks en 2019, y fue un gran cambio de paradigma. El equipo de React espera que Hooks reemplace todos los casos de uso de Class Component, y las bibliotecas populares ya han migrado hacia esta dirección, por ejemplo, React Navigation 5.0 y React Redux 7.1.0 introdujeron sus API Hook.

Conceptualmente, los componentes de React siempre han estado más cerca de las funciones, y la forma de “pensar en React” se volvió más sencilla con Hooks.

La motivación detrás de Hooks explica los beneficios:

Los ganchos le permiten dividir un componente en funciones más pequeñas según las partes relacionadas (como configurar una suscripción o obtener datos), en lugar de forzar una división basada en los métodos del ciclo de vida. También puede optar por administrar el estado local del componente con un reductor para hacerlo más predecible.

Efectos secundarios y cierre de los componentes

Basado en la herencia del prototipo, se dice que las funciones de JavaScript son ciudadanos de primera clase, lo que significa que pueden ser:

  • asignado a variables
  • utilizado como parámetros funcionales
  • devuelto de una función

Estos se aplican igualmente al componente funcional de React. El cierre de JavaScript también es un elemento esencial al usar Hooks.

Un cierre es una combinación de una función agrupada (encerrada) con referencias a su estado circundante (el entorno léxico). En otras palabras, un cierre le da acceso al alcance de una función externa desde una función interna. En JavaScript, los cierres se crean cada vez que se crea una función, en el momento de la creación de la función. (Documentos web de MDN: cierres)

Al igual que este ejemplo en las Preguntas frecuentes de Hooks, es muy importante comprender cuándo se crea el cierre en el ciclo de vida del componente y usar la función estable en lugar de las variables de estado inestable dentro de Hooks.

Nota: A diferencia del método setState que se encuentra en los componentes de la clase, useState no fusiona automáticamente los objetos de actualización. Puede replicar este comportamiento combinando el formulario de actualización de funciones con la sintaxis de propagación de objetos:

React también proporciona Context API para compartir datos que pueden considerarse “globales” para un árbol de componentes de React, como el usuario autenticado actual, el tema o el idioma preferido.

Verificación de transparencia referencial y tipo estático

JavaScript es multi-paradigma, programación orientada a objetos y programación funcional, y React ha heredado la fuerza de ambos. Pero con Hooks, siento que es más obstinado hacia la programación funcional.

La característica clave de React es la composición de componentes. Los componentes escritos por diferentes personas deberían funcionar bien juntos. Es importante para nosotros que pueda agregar funcionalidad a un componente sin causar cambios en toda la base de código. (Principios de diseño de React)

Al extraer los efectos secundarios de un componente de React, se vuelve más predecible. Puede esperar que el componente genere la misma salida si la entrada es la misma. En palabras más específicas, puede ganar transparencia referencial o ser idempotente.

En la práctica, la transparencia referencial debe asegurarse mediante la verificación de tipo estática y pruebas unitarias suficientes.
Los verificadores y linters de tipo estático, mi preferencia es TypeScript y ESLint, hacen que la experiencia de desarrollo sea más segura y sólida, ya que pueden identificar ciertos tipos de problemas incluso antes de ejecutar su código.

Aunque la configuración puede ser un poco engorrosa cuando inicia un nuevo proyecto, le ayuda a usted y a su equipo a ser mucho más productivos. No veo ninguna razón para no usarlos en 2020.

Pruebas de componentes

Un componente declarativo es más fácil de escribir la prueba, ya que puede centrarse en la interacción pura y la representación del componente.

Con Hooks, puede extraer lógica con estado de un componente para que pueda probarse de forma independiente y reutilizarse. Los enganches le permiten reutilizar la lógica con estado sin cambiar la jerarquía de sus componentes. (La motivación detrás de Hooks)

Creo que React Native Testing Library es ahora una biblioteca de prueba de facto para React Native. Se integra estrechamente con Jest y proporciona metodologías de prueba claras junto con las bibliotecas populares como React Navigation y Redux.

React Test Renderer se desarrolla junto con el núcleo de React. Hace que los componentes de React se conviertan en objetos de JavaScript puros, sin depender del DOM o de un entorno móvil nativo.

React Native Testing Library (o RNTL) se basa en React Test Renderer. Agrega API útiles como renderizar (a getByText, queryAllByA11yRole,…), fireEvent, waitFor y act. Se inclina a centrarse en la experiencia del usuario y la accesibilidad.

React Hooks Testing Library para escribir hooks personalizados de prueba que no estén directamente vinculados a un componente o complejo que sea difícil de probar a través de interacciones de componentes.

Conclusión

Entiendo que ha habido y siempre habrá un debate entre el desarrollo de aplicaciones React Native vs Native.

Pero como desarrollador de JavaScript, React y React Native en sí mismo es un marco muy interesante e inspirador para aprender. Aprovecha la capacidad de JavaScript al máximo nivel y está repleto de las mejores prácticas.

A través del proceso de aprendizaje, tuve ganas de obtener una comprensión más profunda del lenguaje JavaScript en sí. Espero que este artículo transmita entusiasmo.