> Manuales > Manual de Lit

Qué es el ciclo de vida de los componentes, por qué es tan importante en el desarrollo con la librería Lit y en Web Components en general. Qué métodos del ciclo de vida tenemos disponibles en el estándar y en el desarrollo con Lit.

Ciclo de vida componentes Lit

El ciclo de vida es una de las herramientas que tenemos para ejecutar código en el preciso momento que se necesite, durante la vida de un componente. Por ejemplo, conseguir que el componente reaccione cuando se ha inicializado, cuando se usa en un documento HTML, cuando alguien manipula una de sus propiedades, etc.

Este tema es fundamental para el desarrollo de componentes y poder realizar comportamientos de todo tipo. De hecho, aunque hasta ahora en el Manual de Lit hemos hecho solo componentes sencillos, ya nos hemos visto obligados a implementar algunos métodos del ciclo de vida.

Qué es el ciclo de vida de los componentes

Básicamente es un resumen de los estados o situaciones por las que puede pasar un componente durante todo el tiempo en el que está presente en una página web. Incluso antes de estar presente en el documento pasa por estados de su ciclo de vida.

Las funciones callback del ciclo de vida de los componentes nos permiten como desarrolladores definir código, para que se ejecute en el preciso instante que un elemento pasa por algún hito de su ciclo de vida.

Qué son funciones callback

Las funciones callback son funciones que se definen en algún lugar del código y se ejecutan de manera automática al producirse ciertas situaciones. Por ejemplo, podemos tener una llamada Ajax y ejecutar una función callback cuando se ha recibido el resultado.

El concepto de callback viene de Javascript en general, no de Web Components o jQuery. Simplemente son funciones que se llaman de vuelta. Se suelen usar en la programación asíncrona para conseguir realizar procesos cuando terminan los procesos asíncronos. En este artículo puedes encontrar más información sobre las funciones callback en Javascript.

Pues bien, nosotros podemos asociar funciones callback a los métodos del ciclo de vida, que se ejecutarán en el momento en el que éstos están siendo utilizados y vayan recorriendo esas etapas marcadas por el ciclo de vida.

Cuáles son los métodos del ciclo de vida de los componentes Lit

En componentes Lit disponemos de dos grupos de métodos del ciclo de vida. Son los siguientes:

Métodos nativos del ciclo de vida

Primero que todo te vamos a dar una referencia a un artículo que explica cuáles son los métodos del ciclo de vida de Web Components, ya que ahí los tienes todos perfectamente explicados.

Por enumerarlos, son los siguientes:

Dentro de estos métodos nativos del ciclo de vida son especialmente útiles el constructor, connectedCallback y disconnectedCallback. Hemos visto ejemplos del constructor y ahora veremos algún ejemplo de los otros dos.

Además tenemos attributeChangedCallback que en Lit no se suele usar, porque justamente los métodos del ciclo de vida de Lit vienen a cubrir y extender las funcionalidades de este método, y adoptedCallback que es algo muy raro y avanzado.

Para ser sincero, nunca he necesitado usar adoptedCallback, por lo que no vamos a ver ejemplos en este manual.

Métodos del ciclo de vida incorporados por Lit

La librería Lit incorpora además otros métodos del ciclo de vida que son propios y que, como decía, vienen a cubrir casos extra relacionados con la reactividad de los componentes incorporada en la librería.

Estos métodos son bastante más avanzados y los vamos a cubrir con detalle más adelante, mostrando ejemplos relevantes, pero vamos a citar aquí los que se usan más a menudo.

El ciclo de vida de los componentes Lit es bastante sofisticado, por lo que solo hemos visto nombres de algunos métodos que deberían comenzar a sonarte. Más adelante los explicaremos y veremos ejemplos.

Manejadores de eventos y el ciclo de vida

Vamos a ver ahora un uso muy importante de los métodos del ciclo de vida, en concreto de los métodos nativos del estándar de Web Components, que debemos aplicar cada vez que un componente haga uso de manejadores de eventos que no son asignados de manera declarativa en el template del componente.

Cuando los manejadores de eventos son declarados en el template, la propia librería Lit se encarga de asociarlos a los elementos y retirarlos cuando el componente deja de existir, por lo que no debemos preocuparnos de mucho. Pero si nosotros de manera imperativa queremos definir eventos, debemos de ser cuidadosos para que estos eventos no permanezcan en ejecución cuando el componente deja de existir. Debido a esta importante situación vamos a comenzar por aquí el tema del ciclo de vida.

¿Cuándo necesitamos definir eventos fuera de los templates?

Esto se hace muy a menudo y para infinidad de situaciones. Pero sobre todo lo harás cuando los manejadores no los quieres asociar a partes del shadow DOM definidas en el template, sino sobre la propia etiqueta host del componente, sobre los elementos hijos que hay en el DOM local del componente, o sobre elementos padre u objetos como document o window.

Por ejemplo, imagina un componente que está atento a situaciones en las que el usuario redimensiona la ventana del navegador. Entonces tendrá que crear eventos en el objeto window. O un componente que define eventos a ejecutar cuando se hace scroll en la página, del mismo modo tendrá que definir el manejador sobre el objeto window.

Pero también puede que necesitemos definir comportamientos periódicos, como un auto-save en un componente de formulario, que envía los datos al servidor cada minuto. En un caso especial como éste puede ocurrir que el auto-save siga en marcha incluso aunque el componente ya no se encuentra en la página. Todo eso lo tenemos que controlar.

Ejemplo de manejadores definidos en conectedCallback y disconnectedCallback

Vamos a mostrar un ejemplo sencillo de definición de eventos fuera del template. Consiste en un componente que informa de la posición del ratón cuando se hace clic en cualquier parte del documento.

Ese informe de la posición del clic lo tenemos que hacer como un evento asignado al documento, ya que queremos detectar los clics en cualquier lugar de la página.

Nuestro componente es muy sencillo. Lo vamos a ver todo de una vez:

import { LitElement, html, css } from 'lit';

const showClickPosition = (e) => {
    console.log('Has hecho clic en ', e.clientX, 'x', e.clientY);
} 

export class DwEventAddRemove extends LitElement {
    static styles = [
        css`
            :host {
                display: block;
            }
        `
    ];

    connectedCallback() {
        super.connectedCallback();
        document.addEventListener('click', showClickPosition);
    }

    disconnectedCallback() {
        super.disconnectedCallback();
        document.removeEventListener('click', showClickPosition);
    }
}
customElements.define('dw-event-add-remove', DwEventAddRemove);

Es interesante apreciar que removeEventListener() requiere recibir el nombre de la función que se debe eliminar de los manejadores de eventos. Por este motivo también habíamos definido esa función de manera externa, para que podamos acceder a ella tanto a la hora de hacer el addEventListener como del removeEventListener.

Para probar este ejercicio necesitarás quitar el elemento del DOM. Esto lo puedes hacer fácilmente desde las herramientas de desarrolladores de tu navegador. Para ello, desde la pestaña "Elements" de las herramientas de desarrolladores, haciendo clic derecho en el elemento que deseas borrar, seleccionas "Delete element".

Eliminar un elemento del DOM con las herramientas de desarrolladores

Como práctica para ti, te sugerimos observar qué pasaría si el manejador del evento no lo retiramos mendiante el callback disconnectedCallback, para darte cuenta de la importancia de usar este método del ciclo de vida del componente.

Conclusión a la introducción al ciclo de vida de los componentes Lit

Esta ha sido una sencilla introducción al ciclo de vida de los componentes en general, basados en la librería Lit y por tanto también en el estándar de Web Components. Hemos empezado por ejemplos sencillos pero que creo que son bastante relevantes sobre lo que respecta al desarrollo de componentes en la vida real.

En futuros artículos vamos a seguir profundizando en el ciclo de vida, ya que es un punto fundamental en el día a día del desarrollo de componentes.

Miguel Angel Alvarez

Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...

Manual