В Lit управление состоянием компонентов строится вокруг реактивных свойств. Любое изменение реактивного свойства автоматически инициирует повторный рендеринг соответствующего компонента. Это позволяет создавать интерфейсы, где представление всегда синхронизировано с данными, без необходимости вручную управлять DOM.
В Lit свойства объявляются с использованием декоратора
@property или через статическое свойство
properties класса компонента:
import { LitElement, html, css } from 'lit';
import { property } from 'lit/decorators.js';
class CounterComponent extends LitElement {
@property({ type: Number }) count = 0;
render() {
return html`
<div>Счетчик: ${this.count}</div>
<button @click=${() => this.count++}>Увеличить</button>
`;
}
}
customElements.define('counter-component', CounterComponent);
Ключевые моменты:
type задает тип свойства и влияет на десериализацию
атрибутов.count вызывает повторный вызов
render().В Lit различают два уровня состояния: локальное (внутри компонента) и глобальное (доступное нескольким компонентам).
Локальное состояние управляется реактивными свойствами компонента. Оно изолировано и не влияет на внешние компоненты напрямую. Использование реактивных свойств для локального состояния обеспечивает чистый и предсказуемый рендеринг.
Глобальное состояние может реализовываться через внешние хранилища или паттерны подписки:
import { reactive } from 'lit';
export const store = reactive({
theme: 'light',
toggleTheme() {
this.theme = this.theme === 'light' ? 'dark' : 'light';
}
});
Компонент может подписываться на изменения:
class ThemeToggler extends LitElement {
render() {
return html`
<button @click=${() => store.toggleTheme()}>
Тема: ${store.theme}
</button>
`;
}
}
customElements.define('theme-toggler', ThemeToggler);
Ключевые моменты:
reactive() позволяет создавать объекты, изменения
которых отслеживаются Lit.Эффективная организация состояния требует разбиения его на отдельные сегменты:
class TodoList extends LitElement {
@property({ type: Array }) todos = [];
get remaining() {
return this.todos.filter(todo => !todo.completed).length;
}
render() {
return html`
<div>Осталось дел: ${this.remaining}</div>
`;
}
}
Lit оптимизирует ререндеринг, вызывая его только при изменении реактивных свойств. Для крупных компонентов важно минимизировать лишние обновления:
shouldUpdate(changedProperties) позволяет
контролировать, когда компонент должен обновляться.class OptimizedComponent extends LitElement {
@property({ type: Number }) value = 0;
shouldUpdate(changedProperties) {
return changedProperties.has('value') && this.value % 2 === 0;
}
render() {
return html`<div>Value: ${this.value}</div>`;
}
}
Для синхронизации нескольких компонентов используются события и подписки на хранилища:
class GlobalCounter extends LitElement {
connectedCallback() {
super.connectedCallback();
window.addEventListener('increment', this._onIncrement);
}
disconnectedCallback() {
window.removeEventListener('increment', this._onIncrement);
super.disconnectedCallback();
}
_onIncrement = () => {
this.count++;
};
render() {
return html`<div>Глобальный счетчик: ${this.count}</div>`;
}
}
Преимущества:
shouldUpdate.Эти подходы обеспечивают предсказуемую архитектуру, оптимальную производительность и гибкость при масштабировании приложений на Lit.