React vs Angular. La historia detrás de una elección.

polbac
Trocafone
Published in
7 min readFeb 11, 2019

TL;DR Resultados y conclusiones post realización de un Proof of Concept: Angular 7 vs React + MobX para una plataforma específica.

En Trocafone comenzamos un interesante proyecto:
el relanzamiento de nuestra plataforma de Trade-in con el objetivo de mejorar la experiencia de usuario y performance.

Optamos por realizar una webapp y necesitábamos elegir una tecnología de front-end moderna y adaptable a nuestras necesidades. Las opciones eran bastante claras: React o Angular. Evaluamos en un momento VUE pero creímos que todavía le faltaba algo de maduración.

Si bien la comunidad front-end está pusheando con React como la mejor opción y al mismo tiempo hay grandes casos de éxito, en el equipo de Trocafone no tomamos decisiones sin hacer análisis y testeos.

Decidimos ir un poco más allá e invertir tiempo en un Proof of Concept de ambas tecnologías: un mismo proyecto prototipo en dos versiones: Angular 7 y React + MobX (como state manager)

Proof of Concept

Los aspectos que queríamos analizar eran varios: modularización y componentización, data binding, interacciones con APIs, validación de formularios y modelos de datos, seguridad y protección de módulos, traducciones, asincronismos, entre otros.

Luego de unas semanas, llegamos exitosamente a generar los dos prototipos y sacar nuestras conclusiones.

React

React es una librería creada por Facebook enfocada en UI, su paradigma se asemeja bastante a la programación funcional y propone una sintaxis propia, JSX, que mezcla Javascript con XML para la creación de componentes. Estos componentes poseen un state (donde se almacenan los datos contextuales del componente) y también pueden recibir configuraciones de sus componentes padres a través de las props.

Como React está diseñado principalmente para realizar componentes UI, muchas veces no alcanza para una arquitectura compleja. Un ejemplo de esto es cuando necesitamos comunicar dos componentes que se encuentren en profundidades muy lejanas: todo se vuelve confuso y el código spaghetti aparece.

Para resolver este problema básicamente hay tres opciones: Redux, MobX o React Context Api.

Redux

Es un merge entre Flux (patrón que propone un flow de 1-way-communication, donde los datos viajan en una única dirección) y las conocidas funciones reducers. Luego están los actions que envían payloads a los reducers y estos generan una nueva instancia inmutable del store. Los componentes están conectados a Redux y reciben los datos del store como propiedades.

Los datos viajan en una única dirección y de esa manera hay una clara división de responsabilidades.

MobX

Es una solución un poco más reciente y el paradigma que propone está dentro de los nuevos conceptos de TFRP (Transparently Applying Functional Reactive Programming).

En MobX también esta la capa de store el cuál es formado por diferentes elementos:

  • Observable: se utilizan cuando necesitamos trabajar con arrays, objects, numbers, booleans o instancias de clases. Un observable es una referencia a ese tipo de datos que definamos y lo que posibilita es una reacción reactiva a cualquier campo contenido dentro del mismo (row de array, atributo de objeto o clase).
  • Computed: la manera más fácil de familiarizarnos con este tipo de dato es pensarlo como una celda de una planilla de cálculo que está referenciada a otras celdas, como por ejemplo una operación.
  • Action: son funciones que modifican el state del store.

Algo interesante es que esta tipificación se hace a través del uso de decorators.

Los componentes reciben todo el store como props a través de una inyección de dependencia y desde ahí la comunicación se hace a través de actions.

React Context Api

Esta API viene implementada a partir de la versión 16 de React y lo que propone son dos componentes nuevos en la librería: <Provider /> y <Consumer />.

La idea de un provider es la definición es un contenedor de datos (state) que se utilizará en otros componentes dentro del árbol de renderización. Este es un componente que funciona como un High Order Component generando un contexto para los componentes hijos.

Los componentes hijos se conectan a los providers a través un componente consumer. De esta manera, sin implementar una nueva librería y con el core de React podríamos interactuar entre componentes que se encuentran distantes en el árbol de nuestra aplicación.

Angular 7

Es un Framework front-end mantenido por Google que posee una gran cantidad de objetos para la realización de una webapp. Es importante destacar que durante los distintos releases que fueron lanzándose fue cambiando mucho y la versión actual es muy diferente a la versión 1, utilizada durante mucho tiempo y muy conocida. A partir de la versíon 2 son todas compatibles entre sí, pero no hay una retrocompatibilidad con la 1.

Algo interesante es que Angular funciona con Typescript, destacándose como una solución de sintaxis fuertemente tipada.

Los objetos que angular propone son varios:

  • Modules: permite agrupar distintos objetos como componentes, servicios, pipes, etc generando así la organización de nuestro código por features.
  • Components: conceptualmente se basa en parte en los componentes de React y otro poco en Web Components. Son el conjunto de un controlador y un template (vista), donde además en esta versión pueden recibir propiedades de Input y Ouput.
  • Templates: si bien en Angular no podemos inyectar JS como en el caso de React, las directivas y utilidades que trae son más que suficientes para realizar cualquier tarea.
  • Inject: Es un decorator que nos permite configurar servicios inyectables y disponibles en otros objetos de nuestros módulos. Es el modo que utiliza el framework para manejar las inyección de dependencias.
  • HttpClient: Este servicio ofrece un funcionalidades para conectarnos a cualquier API. Incluye también un Iterceptor que nos sirve como middleware para intervenir cualquier llamada.
  • Routing: es un módulo donde se definen las rutas de nuestra aplicación y las características. Si bien es bastante similar a cualquier utilidad de routing, trae consigo los dos items siguientes que son bastante interesantes.
  • Lazy Modules: En el routing además de definir rutas para componentes, se puede matchear una ruta con un módulo y que su carga sea Lazy. Para esto utiliza los beneficios de Webpack y genera un chunk js que se cargara únicamente cuando ingresamos en la ruta definida.
  • Guards: Estos objetos son súper útiles. Cuando estamos realizando una webapp seguramente necesitamos que haya una capa de seguridad y protección de ciertos módulos / features. Los guards se implementan en las rutas y son unas interfaces que nos permiten definir funciones bypass para que un usuario con cierta configuración ingrese o no a un módulo. También permiten que estas funciones sean asincrónicas (como Observables).
  • Observables: Esto no es un simple feature nuevo que se implementó en esta versión. Aquí podemos decir que Angular (viniendo de la versión 1 — AngularJS) cambió completamente su paradigma. Abandonó su propuesta de MVC (o MV*) clásica y la remplazó por una solución fuertemente reactiva. Para eso incorporó la librería RxJS (que trabaja con flujos asincrónicos, transformaciones, buses de eventos, etc) y la utiliza en varios de sus objetos.
  • Pipes: esta funcionalidad es parte de los templates y permite transformar/procesar strings dentro de nuestos templates. Un hermoso Pipe que trae esta versión de Angular es el pipe ‘async’ que nos permite hacer data-binding de objetos asincrónicos (ya sean Promises u Observables)
  • Testing: viene configurado y andando perfectamente KarmaJS, en el cual podemos correr browsers (de distintos vendors) y en ellos correr los tests que definamos. Trabaja con Jasmin y es super ágil. También podemos hacer Shallow Test de los componentes y sus elementos.
  • CLI: además de levantar un server dev para poder desarrollar o para buildear nuestra aplicación, el cli brinda la posibilidad de generar nuevos módulos, componentes, etc. De esta manera hace más fácil la generación de nuevos objetos.

La decisión

Luego de generar los dos POCs, terminamos eligiendo Angular para este proyecto.

Para nuestra plataforma necesitábamos una tecnología integral que nos provea un contexto ordenado, estable y escalable para poder generar un código mantenible y de calidad. Creemos con seguridad que Angular era el camino correcto más que nada por el tema de seguridad de módulos. Sin embargo, para otros proyectos (como por ejemplo el ecommerce) decidimos usar React.

UI Library

Luego de elegir la tecnología migramos todos nuestros componentes presentacionales (aka Trocafone Base UI) que teníamos codeados anteriormente en CSS/Vainilla a Angular. Estos son:

  • Input
  • Search
  • Dropdown
  • Alert
  • Radio
  • Logo
  • Navigation
  • Button
  • Checkbox
  • Textarea
  • Table
  • Icon

Generando un repositorio (y npm) independiente para poder utilizar desde distintos proyectos.

Conclusión

Lo único constante que hay mundo del front-end, es el cambio. Y cada vez los cambios son más rápidos. Lo que hoy usamos, seguramente en cinco meses será algo viejo. Las tecnologías, los paradigmas, los flujos, etc.

Sin embargo, para encarar cualquier tipo de proyecto, siempre es importante detenerse, tomar un tiempo, y analizar cuál es la mejor opción y no dejarse llevar únicamente por lo hype.

--

--

polbac
Trocafone

Senior Software Engineer con foco en Front-End