Глубокая передача пропсов

В библиотеке Atomico передача пропсов осуществляется через объект props, доступный внутри компонента. Пропсы могут быть как примитивными значениями (string, number, boolean), так и сложными объектами или функциями. Ключевое отличие Atomico от других фреймворков заключается в строгой типизации и реактивности пропсов, что позволяет отслеживать изменения их значений автоматически.

import { c, useProp } from 'atomico';

function MyComponent({ name, count }) {
    useProp('name', name);
    useProp('count', count);

    return <host>{name}: {count}</host>;
}

MyComponent.props = {
    name: String,
    count: Number
};

export default c(MyComponent);

Метод useProp регистрирует проп в реактивной системе, благодаря чему любые изменения значения автоматически приводят к перерисовке компонента. Объявление Component.props определяет типы и значения по умолчанию, что обеспечивает предсказуемое поведение.


Типы пропсов и их реактивность

Atomico поддерживает несколько типов пропсов:

  • String – текстовые данные.
  • Number – числовые значения.
  • Boolean – логические флаги.
  • Object – сложные структуры данных.
  • Array – массивы любых элементов.
  • Function – функции обратного вызова.

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

function Counter({ state }) {
    function increment() {
        state.value = state.value + 1; // это НЕ вызовет обновление
    }

    return <host>{state.value}</host>;
}

Counter.props = {
    state: Object
};

Правильный подход:

function increment(state, setState) {
    setState({ ...state, value: state.value + 1 });
}

Дефолтные значения и валидация

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

MyComponent.props = {
    name: {
        type: String,
        value: "Default Name"
    },
    count: {
        type: Number,
        value: 0
    },
    callback: {
        type: Function,
        value: () => {}
    }
};

Если пропс не передан родительским компонентом, используется значение из value. Типизация предотвращает присвоение некорректных данных и упрощает отладку.


Функции в пропсах

Передача функций через пропсы позволяет реализовать двустороннее взаимодействие компонентов:

function Button({ onClick }) {
    return <host shadowDom>
        <button oncl ick={onClick}>Нажать</button>
    </host>;
}

Button.props = {
    onClick: Function
};

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


Наследование и проброс пропсов

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

function Parent({ title }) {
    return <host>
        <Child title={title} />
    </host>;
}

Parent.props = { title: String };

function Child({ title }) {
    return <host>{title}</host>;
}

Child.props = { title: String };

При изменении title в Parent компонент Child автоматически получает обновлённое значение, благодаря реактивной системе Atomico.


Деструктуризация и динамические пропсы

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

function Profile({ name, ...otherProps }) {
    return <host>
        <h1>{name}</h1>
        <UserInfo {...otherProps} />
    </host>;
}

Profile.props = {
    name: String,
    age: Number,
    email: String
};

Динамическая передача через ...otherProps сохраняет реактивность и позволяет строить универсальные компоненты без жёсткой привязки к конкретным пропсам.


Рекомендации по архитектуре

  • Определять типы пропсов всегда явно, чтобы избежать ошибок при передаче данных.
  • Для сложных объектов использовать неизменяемые структуры или useState/useMemo для отслеживания изменений.
  • Колбэки и функции передавать через пропсы, чтобы обеспечить минимальную связанность компонентов.
  • Проброс пропсов через вложенные компоненты должен сохранять реактивность, не нарушая принцип однонаправленного потока данных.

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