VueJS: El sistema reactivo

32161531614_de543d116e_o.jpg

Ultimo post sobre Vue. Tenía pensado escribir sobre TypeScript con Vue y de Testing con Vue pero creo que es mejor que dediquéis el tiempo al gran trabajo que está haciendo Alex Jover justamente en estos dos apartados 🙂

Dedicamos el último post a entender el sistema interno reactivo de Vue y a cómo funciona su auténtica magia. Como un cambio de un dato por parte del usuario, puede suponer un cambio en la interfaz sin que yo como desarrollador tenga que indicar esta acción directamente.

¿Qué son los sistemas reactivos?

Los sistemas reactivos son aquellos que mantienen una interacción constante con su entorno. Son sistemas que permiten el cambio de estado interno por medio de eventos (externos o internos) que manejan acciones cuando son accionados.

Su propia palabra lo dice: son sistemas que reaccionan al cambio. Los sistemas que reaccionan al cambio suelen estar incluidos dentro de las arquitecturas orientadas a eventos y son  aconsejables cuando se necesita manejar un numero elevado de interacciones tanto internas y externas ya sea con el usuario, con sensores o con otros sistemas.

Los sistemas reactivos se suelen caracterizar por trabajar bien de forma desacoplada y asíncrona y ayudan a generar sistemas que trabajan mejor con datos en tiempo real. Tanto Vue como React son frameworks que se sustentan en el patrón Observer para transformar estados por medios de eventos que puedan producirse en tiempo real a una acción determinada, en este caso renderizar vistas.

La arquitectura de estos sistemas suele ayudar en la abstracción y desacoplamiento de componentes, pero suelen llevar a sistemas más complejos y difíciles de entender y depurar. No digo que sea el caso de Vue o que no se pueda hacer software simple con sistemas reactivos, simplemente expongo que los sitemas reactivos no son la panacea y tienen un contexto muy claro: la interacción instantánea con el usuario.

No todo tiene que ser un sistema reactivo a partir de ahora solo porque en ciertos contextos esté funcionando muy bien.

¿Cómo es el sistema reactivo en VueJS?

El comportamiento interno de un componente de Vue está muy asentado en el patrón MVVM y en el patrón Observer. Para conseguirlo, Vue presenta un sistema interno como es el siguiente:

data.png

Cada vez que instanciamos un componente en nuestra aplicación, Vue se encarga de hacer 3 cosas:

  1. Envuelve los atributos de su objeto de datos (data())  con un método getters y setters que son usados para la obtención y modificación del datos.
  2. Incluye un manejador que observar ante posible cambios de estado interno que es el encargado de  rerenderizar vistas.
  3. Cuando tiene esto preparado, renderizar el template con dichos datos interpolados en el DOM.

A partir de este momento, cuando un datos es modificado por alguna acción del sistema o del usuario, el método setter del dato modificado notifica al cambio al manejador que se encontraba observando el componente.

Este manejador se encarga de volver a renderizar el Virtual DOM que existe en Vue para que posteriormente se realicen los cambios en el DOM real cada X periodos de tiempo.

Las notificaciones de estos setters son realizadas de manera asíncrona y no detienen el flujo ni de renderizado ni de manejo del estado. Es importante tener esto claro, pues podrá darse el caso que algún cambio no se comporte como nosotros queramos. Para tener control de la sincronización del Dom Virtual y el Dom Real, podemos hacer uso del método nextTick().

Lo bueno de todo esto es que este sistema es transparente para el desarrollador.  Es la magia de Vue. Nosotros solo tendremos que jugar con objetos planos de JavaScript y Vue hará el resto.

Para esto es muy importante que tengamos claro un par de advertencias

¿Qué deberíamos tener en cuenta con un sistema como este?

Lo primero de todo es que si queremos que nuestro estado interno notifique de un posible cambio es definir siempre todo dentro de data.

El siguiente estado a es reactivo en el sistema:

var vm = new Vue({
  data: {
    a: 1
  }
});

Si cambio a en el futuro, el sistema reacciona y realiza las acciones oportunas.

En cambio b no es reactivo en el sistema:

vm.b = 2;

La variable no se ha declarado en el tiempo adecuado, en tiempo de instanciación cuando Vue aprovecha para crear los observadores y los setters.

Vue no nos permite crear variables reactivas en la raíz del estado de un componente. Pero si nos deja añadir reactividad a objetos anidados internos. Por ejemplo, si tengo un componente que tiene un objeto llamado someObject puedo añadirle una variable b en tiempo de ejecución y que esta reaccione ante cambios:

Vue.set(vm.someObject, 'b', 2);

Puedes hacer este uso dentro de un componente y no solo usando la instancia de Vue genérica:

this.$set(this.someObject, 'b', 2);

Puede que se dé el caso que necesite añadir más de una variable a un objeto interno del estado para que sea reactivo. Puedes hacer esta cosa fea:

this.$set(this.someObject, 'a', 1);
this.$set(this.someObject, 'b', 2);

O puedes hacerlo todo junto, componiendo objetos:

this.someObject = Object.assign(this.someObject, { a: 1, b: 2 });

Pero cuidado. El ejemplo anterior no funcionará.

Vue no va a hacer nada porque la referencia de someObject sigue siendo la misma y tanto a como b no se convertirán en reactivos. Para conseguir que sean reactivos, simplemente tenemos que indicar que el objeto tenga una referencia nueva. Esto se hace de esta forma:

this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 });

Conclusión

Conocer los peculiaridades internas de una herramienta el por qué y cómo funciona te pueden ayudar en el futuro. ¿Por qué esta propiedad no se me refresca? ¿Por qué esto no funciona como yo creia?

Siempre solemos tirar por la contestación fácil y es que el framework está roto, o mal hecho, o mal diseñado. Sin embargo, la decisión de diseño en este caso esta claro y está bien explicado en su documentación. Puede que no sea perfecto, pero es nuestra responsabilidad saber estas cosas para que el día de mañana no dediquemos más que unos segundos a un bug que sin saberlo, podría llevarnos horas.

Conocer esta forma de trabajar hace que tu mente cambie y que orientes a diseñar más enfocado en cómo es este sistema. Incluso saber cómo son sus peculiaridades pueden ayudar a pensar si Vue y sus sistema reactivo es lo que en realidad necesitas. ¿Mi sistema va a tener muchas interacciones? ¿Necesito opciones en tiempo real? ¿Necesito algo que escale mucho? Quizá esto te aporte complejidad innecesaria que con jQuery ya tenías solucionada y asimilada. Quien sabe.

Nos leemos 🙂

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s