Immutability (иммутабельность) — принцип, при котором объекты данных не изменяются после создания. В контексте FAST Element, иммутабельность играет ключевую роль в эффективном рендеринге и отслеживании изменений.
FAST Element строится вокруг реактивной модели данных. Каждый компонент наследует возможности отслеживания изменений через observable свойства. Однако при работе с вложенными объектами и массивами важно помнить: мутабельные изменения напрямую не обнаруживаются реактивной системой.
Пример мутабельного изменения:
import { FASTElement, html, css, observable } from "@microsoft/fast-element";
class MyComponent extends FASTElement {
@observable items = [1, 2, 3];
}
const component = new MyComponent();
component.items.push(4); // реактивные обновления не сработают
В данном примере добавление элемента через push не
вызовет повторный рендер. Это связано с тем, что FAST Element
отслеживает ссылку на объект, а не внутренние
мутации.
Для корректного обновления состояния необходимо создавать новый объект или массив, а затем присваивать его свойству:
component.items = [...component.items, 4]; // новый массив, срабатывает реактивность
Для сложных объектов используется распространённая практика:
component.user = { ...component.user, age: 30 };
Создание нового объекта или массива гарантирует срабатывание реактивных подписок и корректное обновление DOM.
Использование иммутабельных структур помогает:
Пример оптимизации:
@observable data = { items: [] };
updateItem(index, value) {
this.data = {
...this.data,
items: this.data.items.map((item, i) => i === index ? value : item)
};
}
Такой подход исключает мутирование и гарантирует, что FAST Element обнаружит изменения.
Для сложных сценариев можно использовать специализированные структуры:
Пример с Immer:
import produce from "immer";
this.items = produce(this.items, draft => {
draft.push(4);
});
Immer сохраняет иммутабельность, при этом код остаётся читабельным.
FAST Element использует шаблоны HTML, где привязки работают через реактивные свойства. Иммутабельность критична, когда привязки к массивам:
const template = html<MyComponent>`
<ul>
${x => x.items.map(item => html`<li>${item}</li>`)}
</ul>
`;
Если items изменяется мутабельно, DOM не обновится.
Иммутабельное присваивание гарантирует автоматическое обновление
элементов списка.
Хотите, я подготовлю наглядную схему взаимодействия иммутабельных данных и реактивной системы FAST Element, которая покажет, как изменения распространяются на DOM?