Los hooks del ciclo de vida

Los hooks del ciclo de vida, también llamados lifecycle hooks son unos mecanismos de Angular que reaccionan ante ciertos eventos muy generales, como el inicio o destrucción de un componente, y que nos permiten programar lógicas que se desencadenen cuando se produzcan esos eventos.

Ya hemos tenido contacto en repetidas ocasiones con el método ngOnInit(). Es, sin ninguna duda, el más usado en cualquier aplicación de Angular. Es un método que se desecadena, como ya sabes de sobra, al inicio de un componente, justo después de que se ejecute el constructor de la clase de dicho componente.

Sin embargo, existen otros hooks que pueden resultarnos muy útiles, y que debemos conocer. En el artículo anterior hemos usado ngDoCheck(). Es otro hook, del que vamos a hablar aquí, así como de otros que te interesarán.

LOS PRINCIPALES HOOKS

En Angular existen varios hooks. Además, algunos pueden variar de una versión a otra. Los principales, que existen desde Angular 2 y se han mantenido por su utilidad, son los siguientes:

  • OnInit. Nos permite implementar el método ngOnInit(), que se ejecuta al inicio de un componente, justo después del constructor de la clase. Ya lo hemos utilizado en varias ocasiones.
  • OnChages. Mediante el método ngOnChanges() detecta cambios en una variable que esté bindeada a una propiedad de un componente padre, y que llegue al componente por @Input().
  • DoCheck. Con el método ngDoCheck() detecta cualquier cambio en cualquier parte de la aplicación.
  • OnDestroy. El método ngOnDestroy() se ejecuta cuando se sale de un componente para entrar en otro, o para cerrar la aplicación. Detecta el final del ciclo de vida del componente.

Todos estos hooks requieren, para su uso, ser importados en la lógica del componente donde los vayamos a utilizar, desde @angular/core (es decir, son parte del núcleo de Angular). Además, son interfaces que deben ser implementadas en la clase de dicho componente. Además, en el caso de OnChanges, debemos importar (aunque no implementar) SimpleChanges. El por qué y el cómo de todo esto lo vamos a ver claro con ejemplos. De OnInit no pondremos ningún ejemplo porque ya lo hemos usado hasta la saciedad, y está por todas partes en nuestra aplicación.

EL HOOK OnChanges

Cómo hemos comentado, debemos importar, para usar este hook, las interfaces OnChanges y SimpleChanges. Además, como la primera incluye el método ngOnChanges(), debe ser implementada en la clase del componente y el método debe ser sobrescrito. Este hook detecta los cambios producidos en las variables que están bindeadas a propiedades y que llegan, por @Input(), a nuestro componente. Como ocurre que tenemos una variable así en HeaderComponent (la añadimos en el artículo anterior), es este componente el que vamos a usar para comprobar como funciona este hook. La lógica header.component.ts nos queda así:

Vamos a fijarnos en las líneas resaltadas. En la línea 1 importamos, además de lo que ya teníamos, las interfaces OnChanges y SimpleChanges. Ambas son imprescindibles para usar este hook.

En la línea 8 vemos que implementamos la interfaz OnChanges. Esto es así porque esta tiene un método que deberemos sobrescribir (lo que es el funcionamiento normal de una interfaz). La interfaz SimpleChanges no tiene métodos, si no sólo una propiedad, por lo que no debe ser implementada.

En las líneas de la 15 a la 17 vemos como se emplea el método ngOnChanges(), que es el que nos ofrece la interfaz OnChanges y que debe, como ya sabes, ser sobrescrito. Observa que este método recibe un argumento del tipo SimpleChanges. Cuando se produzca un cambio en la variable bindeada que entra por @Input(), y que, en este ejemplo, se llama lastName, en la consola veremos un mensaje que nos muestra el estado anterior de la variable, y el estado después del cambio. Podemos probarlo pasando a la lista de miembros y pulsando el botón de edición de alguno de ellos. Es en ese momento cuando cambia el valor de lastName, y este hook se dispara, mostrándonos el mensaje en la consola del navegador.

EL HOOK DoCheck

Este es también, un detector de cambios. Sin embargo, hay dos diferencias respecto al anterior. En primer lugar no está supeditado a los cambios de una variable específica. Detecta absolutamente cualquier cambio que se produzca en el componente actual, o en cualquier componente «hijo» (componente «esclavo») del actual. Por ejemplo, nosotros lo tenemos, del artículo anterior, colocado en AppComponent, así que se disparará ante cualquier cambio en cualquier componente de la aplicación.

La otra diferencia es que no detecta específicamente cual es el cambio, si no sólo que ha habido un cambio. Puede ser la carga de un componente, o la pulsación de un botón, o de un tecla en un campo de texto… Cualquier cosa. Por lo tanto, es nuestra responsabilidad comprobar el estado de lo que esperamos que pueda cambiar. Esto es lo que hacemos con AppComponent. Como respuesta a este hook, actualizamos el valor de una variable según el contenido del elemento que tenemos en sessionStorage.

EL HOOK OnDestroy

Este detecta cuando se «descarga» un componente. Es decir, cuando pulsas un enlace para cargar un componente, descargas el que tenías. De cara al usuario, se asume que el componente que tenías, con sus variables, campos, objetos, etc, ha sido destruido. En el momento de iniciarse la descarga (la destrucción) es cuando se dispara este hook. Observa el listado de home.component.ts:

Cuando arrancas la aplicación, se carga este componente. Si ahora pasas a otra parte (por ejemplo, a la lista de miembros), este componente se descarga (se destruye) y podrás ver el correspondiente mensaje en la consola de tu navegador.

CONCLUYENDO

En este artículo hemos visto los hooks más relevantes de Angular. Existen otros, pero son muy específicos y de uso mucho más limitado. En artículos posteriores veremos el uso de algunos de ellos. En este enlace puedes descargarte la aplicación en su estado actual. Por cierto. ¿Recuerdas que te dejé un pequeño ejercicio para resolver? Se trataba de que, tras hacer un cambio en la ficha de un miembro, si se había cambiado el nombre, se actualizara la variable de sessionStorage.  Bien. Pues la respuesta es que, simplemente, no tienes que hacer nada. Como esta variable se ejecuta con el método que lee los datos actualizados del miembro, ya se actualiza directamente. No te enfades. A veces me gusta hacer pequeñas preguntas trampa para poner a prueba al lector.

Por cierto. Verás que, de un artículo a otro, vamos corrigiendo pequeños bugs de la aplicación. Esto es muy normal en el desarrollo. Cuando una aplicación tiene varias opciones posibles, cada una de ellas con diferentes posibles casuísticas, es muy normal que se detecten bugs que no se habían detectado antes. Esto es algo a lo que tienes que acostumbrarte. Te pasará siempre. En programación existe un silogismo, medio en broma, medio en serio, que dice que «Un programa nunca funciona bien a la primera, y si no funciona bien a la primera, ya no funcionará bien nunca». Esto, afortunadamente no es del todo cierto, pero si muy parecido a la realidad. Cuantas más pruebas haces, más bugs encuentras y depuras pero, siempre, habrá alguno en el que no habrías pensado nunca, que se te escapará. Esta profesión es así. Debemos ser minuciosos, para que los bugs sean los menos posibles, y depurarlos tan pronto como se detecten, pero todos los programadores o equipos de programadores del mundo los tenemos. Incluso firmas mundiales de primera línea sacan al mercado productos con bugs. Así que, cuando te ocurra, no te deprimas. Arréglalo, y a otra cosa.
   

Deja un comentario