В Preact, как и в других реактивных фреймворках, управление жизненным
циклом компонентов критично для оптимизации работы приложения и
предотвращения утечек памяти. Метод componentWillUnmount
вызывается непосредственно перед удалением компонента из
DOM. Этот момент позволяет корректно завершить любые процессы,
которые компонент мог запустить за время своей работы: от подписок на
события до таймеров и асинхронных запросов.
componentWillUnmountОчистка таймеров Любые setTimeout
или setInterval, созданные внутри компонента, должны быть
остановлены. Несвоевременное удаление таймеров приводит к тому, что
функции продолжают выполняться даже после удаления компонента, вызывая
ошибки и утечки памяти.
import { Component } from 'preact';
class TimerComponent extends Component {
componentDidMount() {
this.interval = setInterval(() => {
console.log('Тик');
}, 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return <div>Таймер запущен</div>;
}
}
В примере переменная this.interval хранит идентификатор
таймера, а componentWillUnmount гарантирует его корректное
удаление.
Отписка от событий Компоненты часто
подписываются на глобальные события, например, события окна
window или кастомные события через
EventEmitter. Если отписка не выполнена, после удаления
компонента слушатели продолжают работать, создавая потенциальные утечки
и непредсказуемое поведение.
class WindowResizeComponent extends Component {
componentDidMount() {
window.addEventListener('resize', this.handleResize);
}
componentWillUnmount() {
window.removeEventListener('resize', this.handleResize);
}
handleResize = () => {
console.log('Размер окна изменен');
}
render() {
return <div>Слежение за изменением окна</div>;
}
}Отмена асинхронных операций При работе с
fetch, axios или любыми промисами важно
предусмотреть возможность отмены запроса, если компонент удаляется до
завершения операции. Preact не предоставляет встроенного механизма
отмены промисов, поэтому часто используют
AbortController.
class FetchComponent extends Component {
componentDidMount() {
this.controller = new AbortController();
fetch('https://api.example.com/data', { signal: this.controller.signal })
.then(response => response.json())
.then(data => this.setState({ data }))
.catch(err => {
if (err.name === 'AbortError') {
console.log('Запрос отменен');
}
});
}
componentWillUnmount() {
this.controller.abort();
}
render() {
return <div>Данные загружены</div>;
}
}
Использование AbortController позволяет безопасно
остановить сетевой запрос при удалении компонента.
this). Это упрощает их доступ в
componentWillUnmount.componentDidMount или при инициализации, должны иметь
зеркальное завершение в componentWillUnmount.В функциональных компонентах с использованием хуков аналогом
componentWillUnmount является функция очистки в
useEffect. Это позволяет реализовать тот же принцип
безопасного завершения процессов.
import { useEffect } from 'preact/hooks';
function TimerHookComponent() {
useEffect(() => {
const interval = setInterval(() => console.log('Тик'), 1000);
return () => clearInterval(interval);
}, []);
return <div>Таймер через хуки</div>;
}
Функция, возвращаемая из useEffect, выполняется перед
размонтированием компонента, полностью заменяя
componentWillUnmount в функциональных компонентах.
Метод componentWillUnmount критически важен для
управления ресурсами и предотвращения утечек памяти. Он
гарантирует, что все созданные компонентом процессы будут корректно
завершены. Правильная организация очистки ресурсов позволяет
поддерживать производительность приложения на высоком уровне и снижает
вероятность скрытых ошибок, связанных с асинхронными операциями и
глобальными событиями.