React on Rails

Desde Ruby a ES6

React on Rails

React on Rails 1024 768 ResIT

¡Bienvenido al blog de ResIT!

Como equipo, hace tiempo hemos querido tener para contar abiertamente de nuestras experiencias como empresa de software; de nuestros aciertos y fracasos; de herramientas increíbles o de otras no tanto; de metodologías prometedoras y nuestro intento por implementarlas. Y bueno, partir en este momento nos pareció una buena resolución de año nuevo. ¡Vamos al contenido!

Un poco de historia

A lo largo de estos cuatro, años hemos desarrollado en variados lenguajes y tecnologías: Desde Android e iOS nativo a React Native; desde NodeJS con Express, pasando por Go y PHP hasta Ruby on Rails; desde jQuery hasta React o Angular. Todo esto con el fin de obtener experiencia y poder elegir o descartar alternativas con propiedad.

Por otro lado, he podido trabajar con Ruby on Rails desde la universidad, por lo que le tengo un cariño especial. Y, aproximadamente hace un año, comenzamos a utilizar esta tecnología en casi todos los proyectos nuevos.

El principio fue complicado pues no todo el equipo manejaba el framework. Luego vimos grandes mejoras en términos de velocidad de los desarrollos, orden y claridad del código, gestión de la calidad, entre otros beneficios. Además, el hecho de tener un equipo especializado en ciertas tecnologías genera sinergias positivas de cooperación y aseguramiento de la calidad.

Interfaces complejas

Por defecto, Ruby on Rails utiliza archivos Javascript para “adornar” las interfaces HTML. Y esto funciona perfectamente bien en el caso de interfaces simples como formularios, tablas, dashboards estáticos, etc. (obviando los conflictos entre DataTables y Turbolinks).

Sin embargo, ciertos proyectos requieren de interfaces más sofisticadas, interactivas, que no se tengan que recargar tras cualquier acción. Es en este punto que la dupla HTML + Javascript/jQuery obliga a escribir código demasiado engorroso, lleno de listeners de dudosa compatibilidad, modificaciones al DOM poco elegantes, entre otros.

Webpacker + React

Frente a los problemas antes enunciados, y en vista de las necesidades de nuestros clientes, encontramos dos gemas: Webpacker y React-Rails. La primera, complementa el asset pipeline tradicional de Rails por Webpack (o lo puede reemplazar completamente), es decir, todos los assets ahora serán interpretados y disponibilizados por esta herramienta. Si bien implica cierta refactorización de carpetas, los beneficios en velocidad de compilación son geniales, además de todas las funcionalidades que otorga Webpack. Por otro lado, React-Rails disponibiliza ciertos métodos helpers para poder inyectar componentes de React dentro de archivos .html.erb. 

Manos a la obra

Imagine el lector que debe realizar una aplicación web que es en su gran mayoría transaccional y que cuenta con una serie de objetos “normales”, es decir, con campos de texto, fechas, imágenes, etc. De esto se puede preocupar tranquilamente el scaffold de Rails (o el de propio de ResIT).

Sin embargo, en caso de necesitar interfaces más complejas, dinámicas o interactivas, es muy simple de hacer con las herramientas aquí enunciadas. Por ejemplo, en el caso de un formulario de creación de usuario. Supongamos que queremos habilitar la edición de sus permisos sobre todas las acciones de los controladores. En el caso de nuestra aplicación, son bastante complejos (¿por qué no?). Además, el cliente nos ha pedido que los permisos se actualicen automáticamente al hacer clic en los checkbox. Es decir, sin tener que hacer submit del formulario.

user_form.html.erb permissions_form.html.erb

Si ya lo anterior no es lo suficientemente tosco y difícil de entender, nos faltan los espantosos listeners de eventos sobre los formularios, porque el cliente no quiere que la página deba recargarse, si no que cualquier actualización sea asíncrona. Se verían algo así:

user_form.js

Si bien, en este caso puede que no se vea tan terrible, manejar el DOM con jQuery/Javascript tiene una complejidad que degenera en relación a qué tan dinámico y elegante queramos que se vea. Este gráfico explica mejor mi impresión:

Más allá de la cantidad de código o la legibilidad de este, considero que el principal problema es el hecho de tener la vista (.erb) separada de la lógica (.js) y la manera quejumbrosa que ambas partes deben conversar: ya sea a través de Javascript puro o jQuery, que, en cualquier caso, son soluciones parches no aptas para la complejidad de la web moderna.

¿Y con React?

Si intentamos hacer lo mismo que antes pero con React (React 16 + Material UI, por ejemplo) tendríamos las siguientes ventajas:

  • Toda la lógica del formulario estaría encapsulada en un solo archivo.
  • La arquitectura orientada a componentes y el ciclo de vida mismo que implementa React está pensado para aplicaciones de frontend. De esta manera, nos evitamos manipular el DOM directamente y nos abstraemos al estado del componente y sus propiedades (stateprops).
  • El manejo de errores es más elegante, menos verboso.
  • Nos abrimos al universo de Webpack y los millones de paquetes open source que ofrece este ecosistema (redux, sagas, axios y un largo etc.)

De esta manera, nuestro formulario de permisos quedaría de esta manera (o algo parecido):

user_form.erb (desde donde llamamos al componente de React) y PermissionsForm.jsx

De esta manera, tenemos directamente en un solo archivo (PermissionsForm.jsx) toda la lógica asociada a la edición de permisos: render de la vista hacia el usuario, captura de los inputs sobre los elementos del formulario, envío de un PUT al servidor, captura y manejo de la respuesta y manejo de errores. Además, podemos hacer uso de ES6 y toda la elegancia y comodida que permite.

Conclusión

A modo de conclusión, agradecerles por haber llegado hasta acá. Personalmente estoy encantado de poder compartir parte de lo que hemos aprendido haciendo ResIT, tanto en relación con clientes y usuarios como haciendo software. Rails 6 incluirá Webpack de base, imagino que usando Webpacker por lo que no creo vaya a cambiar demasiado de lo que ellos proponen actualmente. El código de React lo pueden encontrar acá.

 

Santiago Martí – [email protected]