Atomico — это современная библиотека для создания веб-компонентов с использованием JavaScript и JSX. Центральная идея заключается в декларативном управлении состоянием компонента и его жизненным циклом, что позволяет создавать высокоэффективные и повторно используемые элементы интерфейса.
В основе Atomico лежит функциональный подход к компонентам, где каждый компонент является функцией, возвращающей описание DOM через JSX. Состояние управляется через встроенные хукоподобные механизмы, что обеспечивает реактивность и чистоту кода.
Компонент в Atomico определяется как функция с аргументом
props:
import { c, useState } from "atomico";
function Counter(props) {
const [count, setCount] = useState(0);
return (
<host shadowDom>
<div>{count}</div>
<button oncl ick={() => setCount(count + 1)}>Increment</button>
</host>
);
}
customElements.define("my-counter", c(Counter));
Ключевые моменты структуры:
<host> — специальный тег,
который заменяет корневой DOM-узел компонента, управляет Shadow DOM,
стилями и событиями.c() — функция-обёртка для регистрации
компонента как кастомного элемента.useState() — реактивное состояние
компонента. Изменение состояния автоматически вызывает повторный
рендер.Atomico реализует понятие реактивного жизненного цикла через хуки:
useState — хранение локального
состояния.useEffect — выполнение побочных
эффектов при изменении зависимостей.useMemo и
useCallback — оптимизация вычислений и
функций, предотвращающая лишние рендеры.useRef — сохранение ссылок на
DOM-элементы или mutable-значения между рендерами.Пример использования useEffect:
import { c, useState, useEffect } from "atomico";
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const id = setInterval(() => setSeconds(s => s + 1), 1000);
return () => clearInterval(id); // очистка при размонтировании
}, []);
return <host>{seconds} секунд прошло</host>;
}
useEffect позволяет интегрировать асинхронные операции и
управлять ресурсами, предотвращая утечки памяти.
Atomico поддерживает композицию компонентов на основе вложенных элементов. Компоненты могут быть переиспользуемыми и настраиваемыми через props:
function Card({ title, content }) {
return (
<host shadowDom>
<h2>{title}</h2>
<p>{content}</p>
</host>
);
}
function App() {
return (
<host>
<Card title="Заголовок" content="Описание карточки" />
<Card title="Ещё один заголовок" content="Другой контент" />
</host>
);
}
Такой подход формирует архитектурный паттерн “композиция поверх наследования”, который уменьшает связность и увеличивает модульность приложения.
Atomico предлагает реактивное состояние через
Signals (useSignal) для более сложной
логики:
import { c, useSignal } from "atomico";
function Slider() {
const value = useSignal(50);
return (
<host>
<input type="range" min="0" max="100" value={value.value}
onin put={e => value.value = e.target.value} />
<span>{value.value}</span>
</host>
);
}
Особенности Signals:
value.value все связанные части интерфейса
обновляются.Atomico легко интегрируется с другими инструментами:
createContext).useEffect и
fetch, обеспечивая реактивное обновление интерфейса.Пример использования контекста:
import { c, createContext, useContext } from "atomico";
const ThemeContext = createContext("light");
function ThemedButton() {
const theme = useContext(ThemeContext);
return <host class={theme}>Нажми меня</host>;
}
Контекст позволяет передавать данные через дерево компонентов без необходимости пробрасывать props на каждом уровне.
useMemo и useCallback для
предотвращения лишних перерасчётов.Эти подходы формируют основу архитектурной дисциплины в проектах на Atomico, делая код масштабируемым и предсказуемым.