Реактивность и State
createState оборачивает объект в Proxy; мутации триггерят $subscribe.
Подписка
Заголовок раздела «Подписка»$subscribe(callback) — подписка на изменения. Возвращает unsubscribe. Обычно callback = render:
const state = createState({ title: "Привет" });
function render() { ui.render(Text(state.title));}
// Подписываемся на изменения:const unsubscribe = state.$subscribe(render);
// Вызываем для первоначального отображения:render();
// Когда подписка больше не нужна (например, при выгрузке плагина):// unsubscribe();Глубокая реактивность
Заголовок раздела «Глубокая реактивность»Вложенные объекты и массивы тоже реактивны — глубокие ключи и push/splice триггерят рендер:
const state = createState({ user: { profile: { name: "Алексей" } }, genres: ["Экшен", "Драма"]});
// 1. Изменение глубоко вложенного свойства (автоматически вызовет рендер)state.user.profile.name = "Иван";
// 2. Модификация массивов (добавление, удаление, сортировка)state.genres.push("Комедия");state.genres.splice(0, 1);Пакетные обновления (Batching)
Заголовок раздела «Пакетные обновления (Batching)»Синхронные мутации батчатся через Promise.resolve() — один вызов подписчика на такт:
const state = createState({ count: 0, lastAction: "none" });
state.$subscribe(() => { console.log("Рендер вызван!");});
// Синхронное изменение нескольких свойств:state.count++;state.lastAction = "increment";state.count += 5;
// В консоли отобразится ровно ОДИН вывод "Рендер вызван!",// так как все обновления объединились в один такт.Код реактивного счетчика
Заголовок раздела «Код реактивного счетчика»Счётчик с $subscribe:
const state = createState({ clicks: 0 });
function render() { ui.render( VStack() .child(Text("Кликов: " + state.clicks)) .child(Button("Кликнуть").onClick(() => state.clicks++)) );}