Списки и циклы

SkateJS — это современная библиотека для создания веб-компонентов на базе стандартов Custom Elements и Shadow DOM. Основная идея SkateJS заключается в том, чтобы упростить работу с реактивными данными и обновлением DOM без необходимости использовать тяжелые фреймворки. Одним из ключевых аспектов работы с компонентами является отображение коллекций данных с помощью списков и циклов.

Массивы и реактивность

SkateJS позволяет отслеживать изменения в свойствах компонентов и автоматически обновлять DOM при изменении данных. Для работы со списками используется свойство props компонента, в котором можно хранить массив объектов:

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

class TodoList extends Component {
  static get props() {
    return {
      items: Array
    };
  }

  render() {
    const { items } = this;
    return (
      <ul>
        {items.map(item => <li>{item.text}</li>)}
      </ul>
    );
  }
}

define('todo-list', TodoList);

В этом примере свойство items представляет собой массив объектов, каждый из которых отображается через метод map(). Любое изменение массива items приведет к повторному вызову render() и обновлению DOM.

Ключевой момент: SkateJS не модифицирует массив автоматически. Для корректного обновления необходимо создавать новый массив или использовать методы, возвращающие новый массив (map, filter, concat) вместо прямого изменения существующего (push, splice).

Циклы в JSX

Для динамического создания элементов списка чаще всего применяется JSX. В SkateJS внутри JSX поддерживаются все стандартные методы работы с массивами, включая map(), filter() и reduce(). Пример с фильтрацией:

render() {
  const { items } = this;
  const activeItems = items.filter(item => item.active);
  return (
    <ul>
      {activeItems.map(item => <li>{item.text}</li>)}
    </ul>
  );
}

Здесь создается новый массив activeItems, состоящий только из активных элементов. Важно помнить, что использование методов, возвращающих новый массив, обеспечивает реактивность компонента.

Ключи элементов списка

При работе с массивами объектов в SkateJS рекомендуется использовать атрибут key для уникальной идентификации элементов списка. Это позволяет библиотеке эффективно обновлять DOM, избегая полного рендеринга при изменении данных:

<ul>
  {items.map(item => <li key={item.id}>{item.text}</li>)}
</ul>

Если ключи не указаны, SkateJS будет использовать индекс массива, что может привести к некорректному отображению при вставке или удалении элементов в середине массива.

Вложенные циклы

SkateJS поддерживает вложенные циклы, что удобно для сложных структур данных, например, группировки элементов:

const categories = [
  { name: 'Фрукты', items: ['Яблоко', 'Банан'] },
  { name: 'Овощи', items: ['Морковь', 'Брокколи'] }
];

render() {
  return (
    <div>
      {categories.map(category => (
        <div>
          <h3>{category.name}</h3>
          <ul>
            {category.items.map(item => <li>{item}</li>)}
          </ul>
        </div>
      ))}
    </div>
  );
}

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

Динамическое добавление и удаление элементов

Для динамического управления массивом свойств можно использовать методы, создающие новый массив:

addItem(text) {
  this.items = [...this.items, { text }];
}

removeItem(index) {
  this.items = this.items.filter((_, i) => i !== index);
}

Использование spread-оператора или методов filter/concat гарантирует реактивное обновление компонента. Прямое изменение массива (this.items.push()) не вызовет рендеринг.

Итерация с условиями

SkateJS позволяет комбинировать циклы и условные выражения для отображения элементов:

render() {
  return (
    <ul>
      {this.items.map(item => item.visible && <li>{item.text}</li>)}
    </ul>
  );
}

В этом примере отрисуются только элементы, у которых visible равен true. Если элемент скрыт, JSX возвращает false, и SkateJS не вставляет его в DOM.

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

При работе с большими списками рекомендуется:

  • Использовать ключи (key) для всех элементов списка.
  • Минимизировать создание новых массивов внутри метода render().
  • Разделять компонент на подкомпоненты, если отдельные элементы имеют сложную логику.
  • Использовать методы массивов, возвращающие новый массив, чтобы обеспечить реактивность без мутирования.

Итоговая структура

SkateJS предоставляет мощные инструменты для работы с списками и циклами, сохраняя реактивность и эффективность. Комбинация JSX, методов массивов и свойств компонентов позволяет строить динамические интерфейсы с минимальными усилиями и высоким контролем над обновлением DOM.

Основные приёмы работы со списками:

  • map() для генерации элементов.
  • filter() для условного отображения.
  • key для идентификации элементов.
  • Spread-оператор или методы concat/filter для реактивных изменений массива.
  • Вложенные циклы для сложных структур данных.

Эти подходы образуют основу для построения масштабируемых и управляемых компонентов в SkateJS.