Atomico — современная библиотека для создания веб-компонентов на
JavaScript с реактивным подходом, вдохновлённым концепциями React.
Основу реактивного поведения в Atomico составляют хуки, среди которых
ключевую роль играют useState и useEffect. Они
позволяют управлять состоянием компонента и отслеживать побочные
эффекты.
useStateuseState используется для создания локального состояния
внутри компонента. Основной принцип: хук возвращает массив из двух
элементов — текущего значения состояния и функции для его
обновления.
Синтаксис:
import { useState, html, component } from "atomico";
function Counter() {
const [count, setCount] = useState(0);
return html`
<div>
<p>Счёт: ${count}</p>
<button oncl ick=${() => setCount(count + 1)}>Увеличить</button>
</div>
`;
}
export default component(Counter);
Особенности useState в Atomico:
useState, используется как начальное значение. Можно
передавать функции для ленивой инициализации:const [data, setData] = useState(() => expensiveComputation());
setCount(prev => prev + 1);
useEffectuseEffect предназначен для управления побочными
эффектами: запросы к API, подписки, таймеры, работа с DOM вне шаблона
компонента. Он запускается после рендера компонента и может зависеть от
определённых значений состояния.
Синтаксис:
import { useEffect } from "atomico";
useEffect(() => {
console.log("Компонент смонтирован или обновлён");
return () => {
console.log("Компонент размонтирован или эффект обновлён");
};
}, [dependencies]);
Особенности useEffect в Atomico:
useEffect, вызывается перед удалением компонента или перед
следующим вызовом эффекта. Это особенно важно для таймеров и
подписок.useState совместно с
useEffect:const [count, setCount] = useState(0);
useEffect(() => {
const timer = setInterval(() => setCount(prev => prev + 1), 1000);
return () => clearInterval(timer);
}, []);
useState и useEffectСочетание этих хуков позволяет строить полноценную реактивную логику. Состояние управляет визуальным представлением, а эффекты синхронизируют компонент с внешним миром.
Пример динамического счётчика с синхронизацией с локальным хранилищем:
const [count, setCount] = useState(
() => Number(localStorage.getItem("count")) || 0
);
useEffect(() => {
localStorage.setItem("count", count);
}, [count]);
В этом примере:
useState инициализирует состояние из
localStorage.useEffect отслеживает изменения count и
синхронизирует их с хранилищем.useEffect.abortController или очистку таймеров, чтобы
избежать утечек памяти.useEffect(() => {
const handler = e => console.log(e.type);
window.addEventListener("click", handler);
return () => window.removeEventListener("click", handler);
}, []);
useEffect(() => {
let mounted = true;
async function fetchData() {
const response = await fetch("/api/data");
const result = await response.json();
if (mounted) setData(result);
}
fetchData();
return () => {
mounted = false;
};
}, []);
const [input, setInput] = useState("");
const [debounced, setDebounced] = useState("");
useEffect(() => {
const timer = setTimeout(() => setDebounced(input), 300);
return () => clearTimeout(timer);
}, [input]);
Хуки useState и useEffect образуют ядро
реактивного подхода в Atomico. Правильное понимание их взаимодействия
позволяет создавать компоненты, управляемые состоянием и чисто
синхронизированные с внешним окружением.