React.Component — базовий клас для створення компонентів із використанням наслідування в React. До появи хуків у версії 16.8 класові компоненти були єдиним способом керувати станом і життєвим циклом. Згідно з React, 2024, класові компоненти все ще підтримуються, хоча функціональні з хуками рекомендовані для нових проєктів.
Головне
React.Component — абстрактний клас, який надає вбудовані методи для роботи зі станом, пропсами та життєвим циклом компонента. Щоб створити класовий компонент, потрібно визначити клас, що наслідує React.Component, і реалізувати метод render.
React.Component з'явився в найпершій версії React (2013) і залишався основным способом створення компонентів протягом п'яти років. Екосистема React будувалася навколо класів: компоненти вищого порядку (HOC), render props, контекст — усі ці патерни були реалізовані через класовий синтаксис.
З виходом React 16.8 у 2019 році команда React представила хуки як альтернативу класам. Хуки вирішували ті самі завдання — стан, ефекти, контекст — але без наслідування та складної прив'язки контексту. React.Component залишається повністю підтримуваним, але для нових проєктів рекомендується функціональний підхід.
Мінімальний класовий компонент — клас із єдиним методом render, що повертає React-елемент. render — єдиний обов'язковий метод. Він має бути чистою функцією від this.props і this.state: один і той самий набір пропсів і стану дає однаковий результат.
import React, { Component } from 'react';
class Welcome extends Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
Конструктор виконується перед монтуванням. У ньому викликається super(props) для передачі пропсів у батьківський клас та ініціалізується this.state. Використовувати конструктор для інших цілей — підписки, виклики API — не рекомендується; для цього є componentDidMount.
class Counter extends Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
render() {
return <p>Count: {this.state.count}</p>;
}
}
this.state — об'єкт, що містить дані компонента. Змінювати його безпосередньо (this.state.count = 1) заборонено — це не викликає повторного рендеру та ламає передбачуваність. Оновлювати стан потрібно через this.setState, який створює новий об'єкт стану та запускає повторний рендер.
setState може приймати об'єкт або функцію. Функціональна форма є кращою, коли новий стан залежить від попереднього: this.setState(prev => ({ count: prev.count + 1 })). React може групувати кілька setState в один батч для оптимізації продуктивності.
class Toggle extends Component {
constructor(props) {
super(props);
this.state = { isOn: false };
}
handleClick() {
this.setState(prev => ({ isOn: !prev.isOn }));
}
render() {
return (
<button onClick={() => this.handleClick()}>
{this.state.isOn ? 'ON' : 'OFF'}
</button>
);
}
}
Важлива властивість setState — він асинхронний. Після виклику setState стан не оновлюється миттєво. Якщо потрібно виконати дію після оновлення, передайте колбек другим аргументом: this.setState(newState, () => console.log(this.state)).
Класові компоненти мають визначені методи, які React викликає в певні моменти. Монтування — constructor → render → componentDidMount. Оновлення — render → componentDidUpdate. Демонтування — componentWillUnmount.
| Метод | Фаза | Призначення |
|---|---|---|
| constructor | Монтування | Ініціалізація стану та прив'язка методів |
| render | Кожного разу | Повернення React-елементів (обов'язковий) |
| componentDidMount | Після монтування | Запити API, підписки, таймери |
| componentDidUpdate | Після оновлення | Реакція на зміну пропсів/стану |
| componentWillUnmount | Перед видаленням | Очищення підписок, таймерів, відписка від подій |
componentDidMount — основне місце для побічних ефектів після першого рендеру. Тут виконуються HTTP-запити, встановлюються WebSocket-з'єднання та запускаються таймери. Якщо не очистити підписку в componentWillUnmount, виникає витік пам'яті.
class UserProfile extends Component {
componentDidMount() {
fetch(`/api/users/${this.props.userId}`)
.then(res => res.json())
.then(data => this.setState({ user: data }));
}
componentWillUnmount() {
// Cancel request on unmount
}
render() {
return <div>{this.state.user?.name}</div>;
}
}
У JavaScript методи класу за замовчуванням не прив'язані до екземпляра. Якщо передати метод як колбек — в обробник подій, у таймер — this буде undefined (у строгому режимі) або window (без строгого режиму). Без прив'язки this.setState викине помилку.
Існує три способи прив'язки: bind у конструкторі, стрілкова функція в колбеку та class field зі стрілковою функцією. Перший спосіб — офіційна рекомендація React: прив'язати один раз у конструкторі, без перестворення функції на кожен рендер.
// Method 1: bind in constructor (recommended)
class MyComponent extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({ clicked: true });
}
render() {
return <button onClick={this.handleClick}>Click</button>;
}
}
Class field — сучасний синтаксис з автоматичною прив'язкою. Стрілкова функція у властивості класу захоплює this з області видимості конструктора. Недолік — метод створюється на кожному екземплярі, а не на прототипі, що збільшує пам'ять для сотень компонентів одного типу.
Вибір між класом і функцією — не лише питання синтаксису. Функціональні компоненти з хуками вирішують проблеми, притаманні класам: дублювання логіки в різних lifecycle-методах (componentDidMount + componentDidUpdate), складність із this і неможливість витягти пов'язану логіку в перевикористовуваний блок.
Функціональні компоненти легше тестувати — вони не мають внутрішнього стану (який до хуків був лише в класах) і не потребують монтування в DOM для перевірки колбеків. React рекомендує функціональні компоненти для всіх нових проєктів; документація та приклади пишуться на них.
Класові компоненти залишаються найкращим вибором при роботі з легасі-кодом. Якщо проєкт розпочато до 2019 року, у ньому, ймовірно, тисячі класових компонентів. Переписувати їх усі на хуки за один спринт — ризиковано. React гарантує зворотну сумісність: класові компоненти не будуть видалені.
Поступова міграція починається з аналізу компонента. Прості компоненти без стану (stateless) переводяться першими — вони тривіально замінюються функціями. Потім — компоненти з одним-двома state-полями, де useState безпосередньо замінює this.state і this.setState.
Складні компоненти з безліччю lifecycle-методів переводяться через useEffect. Логіка з componentDidMount + componentDidUpdate розбивається на окремі useEffect із різними залежностями. componentWillUnmount замінюється return-функцією всередині useEffect. Для складної логіки стану використовуйте useReducer.
Інструменти автоматичної міграції — @phenomnomnominal/ts-react-class-to-hook або codemod-скрипти — можуть автоматично конвертувати прості класи. Для складних випадків міграція залишається ручною роботою, що потребує розуміння логіки вихідного компонента.
Часті запитання
Так. super(props) передає пропси в батьківський React.Component. Без цього виклику this.props буде undefined всередині конструктора. У render і lifecycle-методах пропси доступні навіть без super, але це побічна поведінка реалізації.
React групує кілька викликів setState в один батч для зменшення кількості зайвих повторних рендерів. Якби setState був синхронним, кожен виклик викликав би негайний рендер, знижуючи продуктивність при масових оновленнях.
Ні. Хуки працюють лише у функціональних компонентах. Для проєктів із класовими компонентами доступні всі старі патерни: render props, HOC і Consumer для контексту. Міграція на хуки вимагає перетворення класу на функцію.
React.PureComponent реалізує shouldComponentUpdate з поверхневим порівнянням пропсів і стану. На відміну від Component, який завжди рендерить повторно при setState, PureComponent пропускає повторний рендер, якщо дані не змінилися. Це оптимізація для компонентів без складної вкладеності.
Використовуйте componentDidCatch і getDerivedStateFromError. componentDidCatch(error, info) логує помилку. getDerivedStateFromError оновлює стан для відображення fallback-UI. Ці методи працюють лише в класових компонентах — функціям потрібен ErrorBoundary-компонент-обгортка.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також