В Atomico управление жизненным циклом компонентов строится вокруг явного и аккуратного подключения и отключения элементов от DOM. Понимание механизма отключения от DOM необходимо для предотвращения утечек памяти, правильного завершения асинхронных операций и корректной очистки ресурсов.
Каждый компонент в Atomico проходит через несколько этапов:
component.useState или useReducer.Для отключения существует специальный механизм, основанный на функции
onUnmount. Она регистрирует коллбеки, которые будут вызваны
при удалении компонента из DOM.
onUnmountФункция onUnmount используется внутри тела компонента.
Ее синтаксис:
import { component, useState, onUnmount } from "atomico";
function Timer() {
const [seconds, setSeconds] = useState(0);
const interval = setInterval(() => {
setSeconds(s => s + 1);
}, 1000);
onUnmount(() => {
clearInterval(interval);
console.log("Компонент удалён, таймер остановлен");
});
return <host>{seconds}</host>;
}
export default component(Timer);
Ключевые моменты:
onUnmount, будут вызваны один
раз при удалении компонента.onUnmount гарантирует очистку ресурсов, особенно
таймеров, подписок на события и сторонних библиотек.Когда компонент регистрирует обработчики событий, важно их удалять
при отключении. Пример с событием click:
function ClickCounter() {
const [count, setCount] = useState(0);
const handleClick = () => setCount(c => c + 1);
document.addEventListener("click", handleClick);
onUnmount(() => {
document.removeEventListener("click", handleClick);
});
return <host>Кликов: {count}</host>;
}
export default component(ClickCounter);
Без onUnmount обработчик останется активным даже после
удаления компонента, что приведёт к утечке памяти и некорректным
обновлениям.
Асинхронные операции, такие как fetch или таймеры, могут
продолжать работать после удаления компонента. onUnmount
позволяет остановить их безопасно:
function DataLoader() {
const [data, setData] = useState(null);
let controller = new AbortController();
fetch("/api/data", { signal: controller.signal })
.then(res => res.json())
.then(setData);
onUnmount(() => {
controller.abort();
console.log("Асинхронная операция отменена");
});
return <host>{data ? JSON.stringify(data) : "Загрузка..."}</host>;
}
export default component(DataLoader);
Если компонент содержит дочерние компоненты, onUnmount
вызывается рекурсивно для каждого элемента дерева. Это означает, что
очистка ресурсов может быть распределена между несколькими уровнями, и
нет необходимости вручную обрабатывать дочерние компоненты. Однако
рекомендуется проверять асинхронные операции на верхнем уровне, чтобы
избежать лишнего выполнения после удаления.
Atomico предоставляет удобный способ комбинировать эффекты с
onUnmount через useEffect:
import { useEffect } from "atomico";
function EffectExample() {
useEffect(() => {
const id = setInterval(() => console.log("tick"), 1000);
return () => clearInterval(id); // автоматически вызывается через onUnmount
}, []);
return <host>Эффект активен</host>;
}
export default component(EffectExample);
В этом примере функция очистки внутри useEffect
эквивалентна регистрации через onUnmount.
onUnmount.AbortController или
аналогичные механизмы отмены.Правильное использование механизма отключения от DOM обеспечивает устойчивость приложения, предотвращает утечки памяти и упрощает управление состоянием компонентов в больших проектах.