Коротка відповідь
juniorУ класових компонентах підписку слід створювати в `componentDidMount`, а відписку — у `componentWillUnmount`. Це гарантує, що слухач буде активний лише під час існування компонента і не залишить «мертвих» колбеків після його видалення.
Повне пояснення
Що це і навіщо
Підписка на події (наприклад, window.addEventListener('resize', ...)) створює зв’язок між зовнішнім джерелом і компонентом. Якщо не відписатися, колбек продовжуватиме викликатися навіть після того, як компонент був видалений з DOM.
Ключові принципи
- componentDidMount – викликається одразу після монтування, коли DOM вже доступний.
- componentWillUnmount – викликається перед демонтажем, коли компонент більше не потрібен.
- Відписка (
removeEventListener) очищає ресурси і запобігає витоку пам’яті.
Як це працює
- При монтуванні компоненту
componentDidMountдодає слухача. - Коли користувач переміщається або компонент видаляється,
componentWillUnmountвикликаєremoveEventListener, що знімає зв’язок.
Практика і реалізація (React клас)
class MyComponent extends React.Component {
componentDidMount() {
window.addEventListener('resize', this.handleResize);
}
componentWillUnmount() {
window.removeEventListener('resize', this.handleResize);
}
handleResize = () => {
// логіка
};
}
Тестування
У Jest можна перевірити, що addEventListener викликаний в componentDidMount, а removeEventListener – у componentWillUnmount.
Безпека і приватність
Невідписані слухачі можуть утримувати посилання на великі об’єкти, що підвищує ризик витоку пам’яті.
Чому відписуватися
- Витік пам’яті: колбек зберігає контекст, що не дозволяє збирати сміття.
- Невірна логіка: події продовжують викликатися, коли компонент вже не існує.
- Підвищена продуктивність: видалення непотрібних слухачів зменшує кількість обробок.
Альтернативи
У функціональних компонентах з useEffect підписка й відписка розміщується в одному блоці: useEffect(() => { /* subscribe */ return () => {/* unsubscribe */}; }, []);