React.Component — классовые компоненты и как они работают

Автор: IT Sectr Опубликовано: 2026-07-04 Время чтения: 9 мин

React.Component — базовый класс для создания компонентов с использованием наследования в React. До появления хуков в версии 16.8 классовые компоненты были единственным способом управлять состоянием и жизненным циклом. По данным React, 2024, классовые компоненты по-прежнему поддерживаются, хотя функциональные с хуками рекомендованы для новых проектов.

Главное

  • React.Component — базовый класс, от которого наследуются классовые компоненты через extends Component.
  • Состояние управляется через this.state и обновляется только через this.setState — прямая мутация запрещена.
  • Жизненный цикл включает методы componentDidMount, componentDidUpdate и componentWillUnmount.
  • this в методах класса требует привязки контекста — через bind, стрелочные функции или class fields.
  • Миграция на функциональные компоненты возможна постепенно: хуки и классы могут сосуществовать в одном проекте.

Что такое React.Component?

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: один и тот же набор пропсов и состояния даёт одинаковый результат.

js
import React, { Component } from 'react';

class Welcome extends Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

Конструктор и инициализация состояния

Конструктор выполняется перед монтированием. В нём вызывается super(props) для передачи пропсов в родительский класс и инициализируется this.state. Использовать конструктор для других целей — подписки, вызовы API — не рекомендуется: для этого есть componentDidMount.

js
class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  render() {
    return <p>Count: {this.state.count}</p>;
  }
}

Управление состоянием через this.state и this.setState

this.state — объект, содержащий данные компонента. Изменять его напрямую (this.state.count = 1) запрещено — это не вызывает ререндер и ломает предсказуемость. Обновлять состояние нужно через this.setState, который создаёт новый объект состояния и запускает повторный рендер.

setState может принимать объект или функцию. Функциональная форма предпочтительна, когда новое состояние зависит от предыдущего: this.setState(prev => ({ count: prev.count + 1 })). React может группировать несколько setState в один батч для оптимизации производительности.

js
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МонтированиеИнициализация state и привязка методов
renderКаждый разВозврат React-элементов (обязательный)
componentDidMountПосле монтированияЗапросы API, подписки, таймеры
componentDidUpdateПосле обновленияРеакция на изменение пропсов/стейта
componentWillUnmountПеред удалениемОчистка подписок, таймеров, отписка от событий

ComponentDidMount — запрос данных

componentDidMount — основное место для побочных эффектов после первого рендера. Здесь выполняются HTTP-запросы, устанавливаются WebSocket-соединения и стартуют таймеры. Если не очистить подписку в componentWillUnmount, возникает утечка памяти.

js
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>;
  }
}

Привязка контекста this в методах

В JavaScript методы класса по умолчанию не привязаны к экземпляру. Если передать метод как колбэк — в обработчик события, в таймер — this будет undefined (в strict mode) или window (без strict mode). Без привязки this.setState выбросит ошибку.

Существует три способа привязки: bind в конструкторе, стрелочная функция в колбэке и class field со стрелочной функцией. Первый способ — официальная рекомендация React: bind один раз в конструкторе, без пересоздания функции на каждый рендер.

js
// 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) в конструкторе?

Да. super(props) передаёт пропсы в родительский React.Component. Без этого вызова this.props будет undefined внутри конструктора. В render и lifecycle-методах пропсы доступны даже без super, но это побочное поведение реализации.

Почему setState асинхронный?

React группирует несколько вызовов setState в один батч для уменьшения количества лишних ререндеров. Если бы setState был синхронным, каждый вызов вызывал бы немедленный рендер, снижая производительность при массовых обновлениях.

Можно ли использовать хуки внутри классового компонента?

Нет. Хуки работают только в функциональных компонентах. Для проектов с классовыми компонентами доступны все старые паттерны: render props, HOC и Consumer для контекста. Миграция на хуки требует преобразования класса в функцию.

Что такое PureComponent и чем он отличается от Component?

React.PureComponent реализует shouldComponentUpdate с поверхностным (shallow) сравнением пропсов и состояния. В отличие от Component, который всегда ререндерит при setState, PureComponent пропускает ререндер, если данные не изменились. Это оптимизация для компонентов без сложной вложенности.

Как обработать ошибку в классовом компоненте?

Используйте componentDidCatch и getDerivedStateFromError. componentDidCatch(error, info) логирует ошибку. getDerivedStateFromError обновляет state для отображения fallback-UI. Эти методы работают только в классовых компонентах — функциям нужен ErrorBoundary-компонент-обёртка.

Итоги

  • React.Component — базовый класс для компонентов с наследованием, состоянием и методами жизненного цикла.
  • this.state инициализируется в конструкторе, обновляется только через this.setState — прямая мутация запрещена.
  • componentDidMount — основное место для запросов API, подписок и таймеров после первого рендера.
  • componentWillUnmount — обязательная очистка подписок и таймеров для предотвращения утечки памяти.
  • Привязка this обязательна: bind в конструкторе — рекомендуемый способ для методов-колбэков.
  • Хуки заменили классовые компоненты для новых проектов, но классы остаются полностью поддерживаемыми.
  • Миграция на хуки выполняется постепенно: stateless компоненты в первую очередь, сложные — через useReducer и useEffect.

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также