useProp для работы со свойствами

useProp — это хук библиотеки Atomico, предназначенный для управления свойствами (props) веб-компонентов. Он позволяет синхронизировать состояние компонента с внешними данными, получать уведомления о их изменениях и обеспечивать реактивное поведение без необходимости вручную подписываться на события.


Инициализация свойства

Свойство создается с помощью вызова useProp, который принимает имя свойства и опциональные параметры:

import { c, useProp, html } from "atomico";

function MyComponent() {
    const myProp = useProp("myProp", { type: String, value: "default" });

    return html`<p>${myProp.value}</p>`;
}

customElements.define("my-component", c(MyComponent));

Ключевые моменты:

  • type определяет тип данных свойства (String, Number, Boolean, Object, Array).
  • value задает начальное значение свойства.
  • Возвращаемый объект содержит поле .value для чтения и записи свойства.

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

Изменение значения через .value автоматически отражается в DOM и вызывает повторный рендер компонента:

myProp.value = "новое значение";

Atomico отслеживает изменения, и компонент обновляется только при необходимости, что минимизирует перерисовку.


Связывание с атрибутами

Свойства, созданные через useProp, могут быть связаны с атрибутами веб-компонента:

const visible = useProp("visible", { type: Boolean, reflect: true });
  • Параметр reflect: true синхронизирует свойство с HTML-атрибутом компонента.
  • При изменении visible.value атрибут visible на элементе обновляется автоматически, и наоборот.

Наблюдение за изменениями

useProp поддерживает реактивные подписки через свойство .onChange:

const count = useProp("count", { type: Number });

count.onCha nge = (newValue, oldValue) => {
    console.log(`Старое значение: ${oldValue}, новое: ${newValue}`);
};
  • onChange вызывается при каждом изменении значения свойства.
  • Можно использовать для запуска побочных эффектов без внешних хуков типа useEffect.

Свойства сложных типов

Для объектов и массивов требуется особое внимание, чтобы изменения внутри структуры также отслеживались:

const config = useProp("config", { type: Object, value: { theme: "light" } });

config.value.theme = "dark";
config.value = { ...config.value }; // Триггер перерендера
  • Atomico отслеживает только замену ссылки на объект или массив.
  • Для глубокого обновления требуется создавать новый объект/массив при изменении вложенных данных.

Использование с computed-свойствами

С помощью useProp можно строить зависимости между свойствами:

const width = useProp("width", { type: Number });
const height = useProp("height", { type: Number });

const area = useProp("area", { type: Number, value: width.value * height.value });

width.onCha nge = () => area.value = width.value * height.value;
height.onCha nge = () => area.value = width.value * height.value;
  • Обеспечивает реактивное вычисление значений на основе других свойств.
  • Поддерживает синхронизацию без сторонних библиотек состояния.

Свойства по умолчанию и типизация

При объявлении свойства можно использовать:

  • type — определяет ожидаемый тип значения.
  • value — задает дефолтное значение.
  • reflect — управляет синхронизацией с атрибутом.
  • readonly — делает свойство только для чтения внутри компонента.
const title = useProp("title", { type: String, value: "Заголовок", readonly: true });
  • Попытка изменить title.value вызовет предупреждение, что свойство только для чтения.
  • Упрощает контроль состояния компонентов и предотвращает непреднамеренные мутации.

Практические рекомендации

  1. Минимизировать использование сложных объектов без пересоздания ссылок. Это важно для корректного отслеживания изменений.
  2. Использовать reflect только при необходимости. Частая синхронизация с атрибутами может повлиять на производительность.
  3. Подписки через onChange заменяют локальные эффекты. Это снижает количество стороннего кода и делает компоненты более предсказуемыми.
  4. Структурировать вычисляемые свойства через реакции на изменения. Это обеспечивает простое управление зависимостями без сторонних реактивных систем.

useProp является ключевым инструментом для создания реактивных и управляемых компонентов в Atomico. Правильное использование его возможностей позволяет строить компоненты с минимальным кодом, высокой производительностью и удобным интерфейсом для взаимодействия через свойства и атрибуты.