Життєвий цикл класового VS функціонального компонента
Головна відмінність
| Класові компоненти | Функціональні компоненти |
|---|---|
Використовують методи життєвого циклу (componentDidMount, componentDidUpdate, componentWillUnmount та ін.) | Використовують хуки (useEffect, useLayoutEffect, useMemo тощо) |
| React сам викликає методи в потрібний момент | Хуки дають тобі гнучкіший і універсальніший спосіб керувати цими моментами |
| Логіка "розкидана" по різних методах | Логіка "зібрана" в одному місці і може бути винесена в кастомні хуки |
Життєвий цикл класового компонента
Основні стадії та методи:
| Стадія | Метод | Коли викликається | Аналог у хуках |
|---|---|---|---|
| Монтування | constructor() | При створенні екземпляра класу | - |
componentDidMount() | Після першого рендеру і вставлення в DOM | useEffect(() => {...}, []) | |
| Оновлення | componentDidUpdate(prevProps, prevState) | Після оновлення state або props | useEffect(() => {...}, [deps]) |
| Розмонтування | componentWillUnmount() | Перед видаленням з DOM | useEffect(() => { return () => {...} }, []) |
Приклад (класичний)
javascript
class Timer extends React.Component {
state = { seconds: 0 };
componentDidMount() {
this.interval = setInterval(() => {
this.setState({ seconds: this.state.seconds + 1 });
}, 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return <p>Минуло секунд: {this.state.seconds}</p>;
}
}Життєвий цикл функціонального компонента
У "функціональному світі" немає окремих методів - усе вирішується за допомогою хуків.
Основний інструмент - useEffect.
Аналоги стадій:
| Стадія | Як реалізується |
|---|---|
| Монтування | useEffect(() => {...}, []) |
| Оновлення | useEffect(() => {...}, [deps]) |
| Розмонтування | useEffect(() => { return () => {...} }, []) |
Приклад (еквівалент через хуки)
javascript
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const id = setInterval(() => setSeconds(s => s + 1), 1000);
return () => clearInterval(id); // cleanup - аналог componentWillUnmount
}, []);
return <p>Минуло секунд: {seconds}</p>;
}Ключові відмінності в підході
| № | Класовий компонент | Функціональний компонент |
|---|---|---|
| 1 | Розділений на методи (componentDidMount, componentDidUpdate, …) | Усе робиться всередині useEffect із залежностями |
| 2 | Логіка "розмазана" по різних місцях | Логіка згрупована за змістом (хуки можна виносити в кастомні) |
| 3 | Має this і стан через this.state / this.setState | Використовує useState / useReducer, без this |
| 4 | setState - завжди асинхронний і об'єднує об'єкти | useState - працює з будь-якими типами даних, включно з об'єктами і функціями |
| 5 | Один екземпляр класу живе весь час | Функція викликається заново при кожному рендері |
| 6 | Важко перевикористовувати логіку (тільки HOC або render props) | Легко ділити й перевикористовувати через кастомні хуки |
| 7 | Більш "імперативний" стиль | Більш "декларативний" і функціональний стиль |
Ілюстрація
Класовий підхід:
javascript
constructor()
↓
render()
↓
componentDidMount()
↓
componentDidUpdate()
↓
componentWillUnmount()Функціональний підхід:
javascript
Рендер → useEffect(() => {...}, [])
Рендер → useEffect(() => {...}, [deps])
Unmount → cleanup()Чому React перейшов до хуків
- Хуки спрощують код: менше шаблонного коду (
this, bind, конструктор). - Дозволяють розділяти логіку за змістом, а не за стадіями.
- Спрощують перевикористання логіки (через кастомні хуки).
- Краще працюють із TypeScript і функціональним стилем.
- Підтримують Concurrent Rendering (React 18+).
Підсумок
| Аспект | Класовий компонент | Функціональний компонент |
|---|---|---|
| API життєвого циклу | Методи (componentDidMount, componentDidUpdate, componentWillUnmount) | Хуки (useEffect, useLayoutEffect, cleanup-функції) |
| Стан | this.state + this.setState() | useState, useReducer |
| Контекст | contextType | useContext() |
| Складність логіки | Розкидана по методах | Сфокусована в хуках |
| Повторне використання | Через HOC/render props | Через кастомні хуки |
| "this" | Є | Немає |
| Продуктивність / зручність | Більш громіздкий | Більш декларативний і гнучкий |
Головна ідея:
Класові компоненти керують життєвим циклом через окремі методи, а функціональні - через хуки (
useEffect), які об'єднують усю життєву логіку в одному місці і дозволяють легко її перевикористовувати.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.