Обновление и перерисовка

В SkateJS обновление и перерисовка компонентов построены на реактивной системе, которая тесно связана с жизненным циклом веб-компонентов. Основной механизм изменения состояния и повторной отрисовки управляется через свойства (props) и внутреннее состояние (state) компонента.

Реактивность свойств и состояния

Свойства компонента в SkateJS определяются с помощью функции props, где указывается тип, значение по умолчанию и опциональные наблюдатели (observer). Любое изменение свойства автоматически инициирует процесс обновления компонента.

import { Component, props, h } from 'skatejs';

class MyComponent extends Component {
  static props = {
    count: props.number({ default: 0 })
  };

  renderCallback() {
    return <div>Счётчик: {this.count}</div>;
  }
}

customElements.define('my-component', MyComponent);

Ключевой момент: при изменении this.count SkateJS автоматически вызывает renderCallback, что ведёт к обновлению DOM внутри компонента.

Принудительное обновление

Иногда требуется инициировать обновление вручную, например после асинхронной операции. Для этого используется метод update():

async fetchData() {
  const data = await fetch('/api/items').then(res => res.json());
  this.items = data;
  this.update();
}

Метод update() планирует перерисовку компонента на следующем цикле событий, что предотвращает частые и лишние обновления при множественных изменениях состояния.

Жизненный цикл и перерисовка

В SkateJS важную роль играет метод renderCallback, который вызывается после каждого обновления состояния или свойства. Этот метод отвечает за построение виртуального DOM:

  • renderCallback — основной метод отрисовки. Его можно рассматривать как аналог render в React.
  • updated — вызывается после завершения обновления DOM и может использоваться для побочных эффектов, зависящих от нового состояния.
  • shouldUpdate — позволяет оптимизировать перерисовку, предотвращая ненужное обновление компонента, если свойства не изменились критично.
shouldUpdate(prevProps, nextProps) {
  return prevProps.count !== nextProps.count;
}

Делегирование и перерисовка дочерних элементов

Компоненты SkateJS поддерживают вложенную структуру. При изменении состояния родительского компонента дочерние компоненты обновляются автоматически, если они зависят от изменяемых свойств. Для контроля перерисовки дочерних компонентов можно использовать ключи (key) при рендеринге массивов:

renderCallback() {
  return (
    <ul>
      {this.items.map(item => <li key={item.id}>{item.name}</li>)}
    </ul>
  );
}

Использование ключей предотвращает полное пересоздание элементов и позволяет эффективно обновлять только изменившиеся узлы DOM.

Асинхронная перерисовка и очередь обновлений

SkateJS организует обновления через очередь изменений, что минимизирует количество операций перерисовки:

  1. Все изменения свойств добавляются в очередь.
  2. Если несколько свойств изменяются одновременно, вызывается одна перерисовка.
  3. update() можно вызвать вручную для синхронизации с асинхронными данными.
this.prop1 = 10;
this.prop2 = 20;
// Вместо двух рендеров, SkateJS объединяет их в один цикл обновления

Оптимизация производительности

Для сложных компонентов рекомендуется использовать:

  • shouldUpdate для фильтрации ненужных обновлений.
  • Локальное состояние (this.state) для данных, которые не должны триггерить полное обновление компонента.
  • Ключи (key) при работе с динамическими списками.

Эти подходы позволяют управлять объемом операций DOM и поддерживать высокую производительность даже при больших деревьях компонентов.

События и реактивная перерисовка

SkateJS интегрирован с кастомными событиями, которые могут влиять на обновление компонентов. Важно различать:

  • События, влияющие на состояние — приводят к автоматической перерисовке через изменение свойства.
  • События без влияния на состояние — не вызывают обновления, что экономит ресурсы.
handleClick() {
  this.count += 1; // автоматически вызывает renderCallback
}

Итоговое поведение

  • Любое изменение свойства или состояния компонента планирует вызов renderCallback.
  • Очередь обновлений объединяет несколько изменений в один цикл перерисовки.
  • Методы жизненного цикла (shouldUpdate, updated) позволяют оптимизировать и контролировать процесс обновления.
  • Вложенные компоненты обновляются автоматически, если зависят от изменённых данных.

Такой механизм делает SkateJS мощным инструментом для построения реактивных, высокопроизводительных веб-компонентов, обеспечивая гибкость управления обновлением и перерисовкой на уровне отдельного элемента.