> Manuales > Manual de Lit

Método requestUpdate() de los componentes de Lit, que forma parte de las utilidades del ciclo de vida y que permiten solicitar de forma explícita la actualización de una vista (template) de un componente.

Método requestUpdate() de Lit

En este artículo vamos a ver otro de los métodos que forman parte del ciclo de vida de los componentes Lit y sus propiedades. En esta ocasión vamos a abordar el método requestUpdate() que permite solicitar explícitamente al componente que realice una actualización de su vista.

Las actualizaciones de las vistas, o templates de los componentes, se realizan de manera automática en Lit cada vez que las propiedades declaradas del componente cambian. ¿Pero qué pasa si deseo actualizar el template por otros motivos ajenos al cambio de una o más propiedades?

Recuerda que a veces una propiedad puede cambiar pero, si hemos definido el método hasChanged() puede que no se llegue a actualizar el template, porque ese cambio no se considere relevante. Esto lo vimos en el artículo anterior dedicado a hasChanged. Básicamente aprendimos que, si hasChanged devuelve un valor considerado como false no se actualiza el template. Lit internamente dejará de llamar a requestUpdate() para no producir actualizaciones.

Casos de uso de requestUpdate()

Como hemos señalado, en la mayoría de los casos es totalmente innecesario llamar a requestUpdate() de manera explícita, porque el método se invoca cada vez que una de las propiedades reactivas del componente cambia.

Entonces ¿en qué casos podría necesitar invocarlo de manera manual? lo harás cuando tengas que actualizar el template porque haya que mostrar alguna cosa que pueda haber cambiado y que no forme parte de las propiedades declaradas. Por ejemplo puede ocurrir que cada cierto tiempo queramos realizar una actualización, entonces podríamos configurar un temporizador que llamase a requestUpdate(). Puede que estemos desarrollando una aplicación realtime y que necesitemos invocar ese método cada vez que un dato cambie, etc.

Lo cierto es que, si necesitas que se actualice el template cuando algo cambie, simplemente almacenarás ese algo en una propiedad reactiva. Pero si no es el caso, por el motivo que sea, entonces te vendrá bien tener a mano requestUpdate().

Ejemplo de uso de requestUpdate()

El método requestUpdate() es extremadamente sencillo de utilizar y lo veremos con un ejemplo de un componente que mostrará la hora actual.

Lo cierto es que podríamos hacer este componente sin usar requestUpdate, simplemente almacenando la hora a mostrar en una propiedad, pero vamos a tomar otra estrategia que también podría ser válida.

Para empezar quiero mostrar este método render().

render() {
    return html`
        Date.now() = ${Date.now()}
    `;
}

Como puedes ver, el método render() está mostrando el timestamp de la hora actual, justamente lo que devuelve Date.now().

¿Qué crees que ocurrirá? Supongo que lo has adivinado. Simplemente mostrará el timestamp del momento en el que el componente se renderizó y nunca más se actualizará la hora, porque no estamos usando ninguna propiedad reactiva.

Ahora imagina que en ese componente colocamos este código:

firstUpdated() {
    setInterval( () => this.requestUpdate(), 1000);
}

Esto quiere decir que, después de la primera renderización del componente se creará un "interval" de Javascript, para ejecutar un código cada 1000 milisegundos (un segundo). Ese interval hace una llamada al método requestUpdate() del componente. Por lo tanto, cada segundo Lit llevará a cabo una actualización del template invocada por nosotros de manera explícita.

Gracias a ese intervalo, cada segundo se volverá a ejecutar la renderización del componente y podremos ver cómo el template se actualiza constantemente, mostrando cambios en el timestamp de la hora cada segundo que pase.

Este mismo ejemplo lo podríamos mejorar un poco para que, en vez de mostrar el timestamp, mostrase la hora actual. Para ello vamos a hacer uso de un método adicional que se encargará de mostrar la hora, minutos y segundos en un formato legible.

Nuestro método render va a quedar de esta manera:

render() {
    return html`
        <div class="clock">${this.getClock()}</div>
    `;
}

Simplemente invocamos el método getClock(), que se encargará de producir la cadena del reloj que se quería mostrar. Nuestro método getClock() tendrá simplemente que devolver la cadena de la hora actual, en el formato debido.

Podría colocar en el método render directamente todo el código para formatear la cadena del reloj, pero no ayudaría a la lectura del template.

getClock() {
    let date = new Date();
    return `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
}

Ha sido bastante sencillo. Solo hay un detalle relevante que consiste en que el reloj no siempre va a tener dos caracteres para la hora, minutos y segundos, por lo que a veces podría ser algo como "5:1:0" y nosotros querríamos que apareciese como "05:01:00". Para ello simplemente vamos a hacer unas transformaciones extra a esos números para agregar el cero delante si le hace falta:

getClock() {
    let date = new Date();
    return `${date.getHours().toString().padStart(2,0)}:${date.getMinutes().toString().padStart(2,0)}:${date.getSeconds().toString().padStart(2,0)}`;
}

Ya lo tenemos. Hemos construido un reloj que muestra la hora del instante actual, sin usar propiedades reactivas, gracias a la invocación explícita del método requestUpdate() en un intervalo de un segundo.

Código del componente reloj completo

Solamente para que conste, voy a dejar el código de este componente completo.

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

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

    firstUpdated() {
        setInterval( () => this.requestUpdate(), 1000);
    }

    render() {
        return html`
            <div class="clock">${this.getClock()}</div>
        `;
    }

    getClock() {
        let date = new Date();
        return `${date.getHours().toString().padStart(2,0)}:${date.getMinutes().toString().padStart(2,0)}:${date.getSeconds().toString().padStart(2,0)}`;
    }
}
customElements.define('show-clock', ShowClock);

Conclusión

Como has podido comprobar requestUpdate es un método sencillo de usar. Ahora falta encontrarle una utilidad en tu día a día. No te precupes si ahora no ves un modo de usar el método, ya llegará el momento si fuera necesario.

Finalmente creo que es conveniente mencionar otro mecanismo del ciclo de vida muy relacionado con el cambio de las propiedades que puede confundirse con requestUpdate(). Se trata de updateComplete, que es una promesa que se resuelve cada vez que el componente ha terminado de actualizarse y que es muy importante porque los updates de las vistas de los componentes Lit son asíncronos. No voy a adelantar más porque este es justamente el tema que abordaremos en el próximo artículo.

Miguel Angel Alvarez

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

Manual