Reactive controllers are objects that hook into a host element’s lifecycle to encapsulate and reuse stateful logic. A controller implements the ReactiveController interface and registers itself with a host that implements ReactiveControllerHost (such as ReactiveElement or LitElement).
import type {ReactiveController, ReactiveControllerHost} from '@lit/reactive-element';
Called when the host element is connected to the document. Corresponds to connectedCallback() on custom elements. Use this to set up subscriptions, timers, or event listeners.
If a controller is added to an already-connected host via addController(), hostConnected() is called immediately.
Called when the host element is disconnected from the document. Corresponds to disconnectedCallback(). Use this to clean up any resources set up in hostConnected().
Called during the host update cycle, just before the host’s own update() method runs. Not called during server-side rendering. Use this to read DOM state before the update occurs.
Called after a host update, just before firstUpdated() and updated() run on the host. Not called during server-side rendering. Use this to react to DOM changes produced by the update.
An object that can host reactive controllers. ReactiveElement (and therefore LitElement) implements this interface. You can also implement it in non-element classes.
Resolves when the host has finished its current update. Resolves to true if no further update was scheduled, false if a property was set inside updated(). Rejects if an exception occurred during the update.
The following example implements a clock controller that tracks the current time and keeps the host synchronized.
clock-controller.ts
import type {ReactiveController, ReactiveControllerHost} from '@lit/reactive-element';export class ClockController implements ReactiveController { private _host: ReactiveControllerHost; private _timerID?: ReturnType<typeof setInterval>; value = new Date(); constructor(host: ReactiveControllerHost) { this._host = host; host.addController(this); } hostConnected() { // Start the clock when the host connects. this._timerID = setInterval(() => { this.value = new Date(); this._host.requestUpdate(); }, 1000); } hostDisconnected() { // Stop the clock when the host disconnects. clearInterval(this._timerID); this._timerID = undefined; }}
Use the controller in a LitElement:
my-clock.ts
import {LitElement, html} from 'lit';import {customElement} from 'lit/decorators.js';import {ClockController} from './clock-controller.js';@customElement('my-clock')class MyClock extends LitElement { private _clock = new ClockController(this); render() { return html`<p>The time is ${this._clock.value.toLocaleTimeString()}</p>`; }}