Динамическое изменение

Atomico — это современная библиотека для построения веб-компонентов на JavaScript, которая сочетает реактивность и декларативный синтаксис. Динамическое изменение данных и состояния компонентов является одной из ключевых особенностей библиотеки, позволяющей создавать интерактивные интерфейсы без необходимости полного перерисовывания DOM.

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

В Atomico каждое свойство компонента может быть реактивным. Для этого используется функция useProp или объявление свойства через объект props с указанием типа. Изменение значения реактивного свойства автоматически вызывает повторный рендер компонента.

import { c, useProp } from "atomico";

function Counter() {
    const [count, setCount] = useProp(0);

    return (
        <host shadowDom>
            <button oncl ick={() => setCount(count + 1)}>
                Увеличить: {count}
            </button>
        </host>
    );
}

Counter.props = {
    count: Number
};

export default c(Counter);

В примере useProp обеспечивает двустороннюю реактивность: при изменении count интерфейс обновляется автоматически.

Управление состоянием компонента

Для более сложной логики динамических изменений используется useState. Эта функция работает аналогично React, но оптимизирована под веб-компоненты. Она позволяет хранить локальное состояние и изменять его без вмешательства в глобальные данные.

import { c, useState } from "atomico";

function Toggle() {
    const [active, setActive] = useState(false);

    return (
        <host shadowDom>
            <button oncl ick={() => setActive(!active)}>
                {active ? "Включено" : "Выключено"}
            </button>
        </host>
    );
}

export default c(Toggle);

Ключевой момент: useState обеспечивает реактивность только внутри компонента, тогда как useProp позволяет передавать значения извне.

Реактивные эффекты

Для реагирования на изменения свойств и состояния применяется useEffect. Эта функция позволяет выполнять побочные эффекты при обновлении данных. Она принимает callback и массив зависимостей — переменных, за изменением которых нужно следить.

import { c, useState, useEffect } from "atomico";

function Logger() {
    const [value, setValue] = useState("");

    useEffect(() => {
        console.log("Значение изменилось:", value);
    }, [value]);

    return (
        <host shadowDom>
            <input onin put={e => setValue(e.target.value)} value={value} />
        </host>
    );
}

export default c(Logger);

Особенность Atomico: эффекты срабатывают после рендера, что гарантирует согласованность DOM с состоянием компонента.

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

Atomico поддерживает динамическую генерацию DOM через обычные JavaScript-массивы. Для этого используется метод map внутри JSX.

import { c, useState } from "atomico";

function List() {
    const [items, setItems] = useState(["Яблоко", "Банан"]);

    const addItem = () => setItems([...items, `Фрукт ${items.length + 1}`]);

    return (
        <host shadowDom>
            <ul>
                {items.map(item => (
                    <li>{item}</li>
                ))}
            </ul>
            <button oncl ick={addItem}>Добавить</button>
        </host>
    );
}

export default c(List);

Динамическое добавление элементов через map гарантирует, что Atomico обновляет только изменившиеся части DOM, избегая полной перерисовки.

Реактивные списки с ключами

Для сложных списков рекомендуется использовать атрибут key. Он позволяет Atomico правильно отслеживать изменения элементов, минимизируя количество операций DOM.

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

Использование key особенно важно при удалении, добавлении и перестановке элементов.

Взаимодействие с событиями

Atomico упрощает обработку событий и динамическое изменение состояния через on* обработчики. Все события можно привязывать напрямую к JSX-элементам.

<button oncl ick={() => setCount(count + 1)}>+</button>
<input onin put={e => setText(e.target.value)} value={text} />

Особенность: все обработчики автоматически связываются с компонентом, сохраняя контекст реактивного состояния.

Отложенные и условные рендеры

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

{isVisible ? <p>Текст отображается</p> : null}

Такой подход позволяет создавать интерактивные интерфейсы без лишних вычислений, так как скрытые элементы не рендерятся в DOM.

Композиция динамических компонентов

Atomico поддерживает композицию компонентов, где один компонент может динамически включать другие в зависимости от состояния или props.

function Panel({ type }) {
    return (
        <host shadowDom>
            {type === "login" ? <LoginForm /> : <RegisterForm />}
        </host>
    );
}

Динамическая замена компонентов возможна без перезагрузки страницы и без разрушения существующего состояния соседних элементов.

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

Для больших динамических интерфейсов рекомендуется:

  • Использовать key при рендере списков.
  • Ограничивать количество зависимостей в useEffect.
  • Минимизировать вычисления в JSX, вынося их в отдельные функции.
  • Применять useMemo или кэширование данных для часто изменяемых значений (поддерживается через стандартные JS-структуры внутри Atomico).

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