useEffect як заміна методам ЖЦ
1. useEffect() об'єднує кілька стадій життєвого циклу
У класових компонентах у нас є різні методи для різних стадій:
| Стадія | Метод | Коли викликається |
|---|---|---|
| Монтування | componentDidMount() | Після першого рендера |
| Оновлення | componentDidUpdate() | Після кожного оновлення |
| Розмонтування | componentWillUnmount() | Перед видаленням з DOM |
А у функціональному компоненті один useEffect() здатний виконувати всі ці ролі,
залежно від того, як ти вкажеш залежності (deps).
2. Як useEffect поводиться в різних режимах
Монтування (аналог componentDidMount)
useEffect(() => {
console.log('Монтування компонента');
}, []); // порожній масив → викликається лише один разВиконається один раз після першого рендера (і після додавання в DOM). Використовується для:
- завантаження даних,
- підписок,
- ініціалізації.
Оновлення (аналог componentDidUpdate)
useEffect(() => {
console.log('Компонент оновився');
});Без масиву залежностей -> викликається після кожного рендера. З масивом залежностей -> лише якщо змінилося конкретне значення:
useEffect(() => {
console.log('count змінився');
}, [count]);Розмонтування (аналог componentWillUnmount)
useEffect(() => {
console.log('Монтування');
return () => {
console.log('Розмонтування'); // cleanup
};
}, []);Повернення функції з useEffect - це cleanup,
який React викличе перед розмонтуванням компонента.
Використовується для:
- відписки від подій,
- очищення таймерів,
- закриття з'єднань.
3. Один useEffect може виконувати всі три ролі одночасно
useEffect(() => {
console.log('Монтування або оновлення');
const id = setInterval(() => console.log('tick'), 1000);
return () => {
console.log('Очищення перед розмонтуванням або оновленням');
clearInterval(id);
};
}, [count]);Тут один useEffect:
- при першому рендері -> діє як
componentDidMount; - при зміні
count-> якcomponentDidUpdate; - при видаленні або перед новим запуском -> як
componentWillUnmount.
4. Чому React так зробив
Класові компоненти мали окремі фази й методи, але це:
- змушувало дублювати код (один і той самий API-запит у
componentDidMountіcomponentDidUpdate); - ускладнювало об'єднання логіки (наприклад, "підписка + очищення");
- призводило до розрослого коду.
Функціональний useEffect вирішує це:
- усе, що пов'язане з однією логікою ефекту, знаходиться в одному місці;
- React сам вирішує, коли саме викликати ефект і очищення;
- розробник керує поведінкою через залежності.
Порівняння "до" і "після"
Класовий компонент:
class Example extends React.Component {
componentDidMount() {
console.log('Монтування');
}
componentDidUpdate(prevProps) {
if (prevProps.value !== this.props.value) {
console.log('Оновлення');
}
}
componentWillUnmount() {
console.log('Розмонтування');
}
render() {
return <div>{this.props.value}</div>;
}
}Функціональний компонент з одним useEffect:
function Example({ value }) {
useEffect(() => {
console.log('Монтування або оновлення');
return () => {
console.log('Розмонтування');
};
}, [value]);
return <div>{value}</div>;
}Один useEffect замінює одразу три методи, і робить це чистіше та компактніше.
5. Підсумок
useEffect()- це універсальний механізм побічних ефектів, який залежно від залежностей (deps) може замінитиcomponentDidMount,componentDidUpdateіcomponentWillUnmount.
| Поведінка | Класовий метод | useEffect |
|---|---|---|
| Монтування | componentDidMount | useEffect(..., []) |
| Оновлення | componentDidUpdate | useEffect(..., [deps]) |
| Розмонтування | componentWillUnmount | return cleanup з useEffect |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.