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

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

React.Component — основният клас за създаване на компоненти чрез наследяване в React. Преди появата на hooks във версия 16.8, класовите компоненти бяха единственият начин за управление на състоянието и жизнения цикъл. Според React, 2024, класовите компоненти все още се поддържат, въпреки че функционалните с hooks се препоръчват за нови проекти.

Основни точки

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

Какво е React.Component?

React.Component — абстрактен клас, който предоставя вградени методи за работа със състояние, props и жизнения цикъл на компонента. За да създадете класов компонент, трябва да дефинирате клас, който наследява React.Component, и да имплементирате метода render.

React.Component се появи в първата версия на React (2013) и остана основният начин за създаване на компоненти в продължение на пет години. Екосистемата на React беше изградена около класове: компоненти от по-висок ред (HOC), render props, контекст — всички тези модели бяха имплементирани чрез класов синтаксис.

С издаването на React 16.8 през 2019 г., екипът на React представи hooks като алтернатива на класовете. Hooks решаваха същите задачи — състояние, ефекти, контекст — но без наследяване и сложно обвързване на контекста. React.Component остава напълно поддържан, но за нови проекти се препоръчва функционалният подход.

Създаване на класов компонент

Минималният класов компонент — клас с единствен метод render, който връща React елемент. render — единственият задължителен метод. Той трябва да бъде чиста функция на this.props и this.state: същият набор от props и състояние дава същия резултат.

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

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

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

Конструкторът се изпълнява преди монтирането. В него се извиква super(props) за предаване на 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 в един batch за оптимизиране на производителността.

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, състоянието не се актуализира веднага. Ако трябва да извършите действие след актуализацията, предайте callback като втори аргумент: this.setState(newState, () => console.log(this.state)).

Методи на жизнения цикъл

Класовите компоненти имат предефинирани методи, които React извиква в определени моменти. Монтиране — constructor → render → componentDidMount. Актуализиране — render → componentDidUpdate. Демонтиране — componentWillUnmount.

МетодФазаПредназначение
constructorМонтиранеИнициализация на state и обвързване на методи
renderВсеки пътВръщане на React елементи (задължително)
componentDidMountСлед монтиранеAPI заявки, абонаменти, таймери
componentDidUpdateСлед актуализиранеРеакция на промяна на props/състояние
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() {
    // Отказ на заявката при демонтиране
  }

  render() {
    return <div>{this.state.user?.name}</div>;
  }
}

Обвързване на контекста this в методите

В JavaScript методите на класа по подразбиране не са обвързани с инстанцията. Ако предадете метод като callback — на манипулатор на събитие, таймер — this ще бъде undefined (в строг режим) или window (без строг режим). Без обвързване, this.setState ще хвърли грешка.

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

js
// Метод 1: bind в конструктора (препоръчително)
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 от обхвата на видимост на конструктора. Недостатък — методът се създава на всяка инстанция, а не на прототипа, което увеличава паметта за стотици компоненти от един и същи тип.

Сравнение на класови и функционални компоненти

Изборът между клас и функция — не е само въпрос на синтаксис. Функционалните компоненти с hooks решават проблеми, присъщи на класовете: дублиране на логика в различни методи на жизнения цикъл (componentDidMount + componentDidUpdate), сложност с this и невъзможност за извличане на свързана логика в многократно използваем блок.

Функционалните компоненти са по-лесни за тестване — те нямат вътрешно състояние (което преди hooks беше само в класове) и не изискват монтиране в DOM за проверка на callback. React препоръчва функционални компоненти за всички нови проекти, документацията и примерите се пишат с тях.

Класовите компоненти остават най-добрият избор при работа с наследен код. Ако проектът е започнат преди 2019 г., вероятно съдържа хиляди класови компоненти. Преписването им всички на hooks в един спринт е рисковано. React гарантира обратна съвместимост: класовите компоненти няма да бъдат премахнати.

Стратегия за миграция от класове към hooks

Постепенната миграция започва с анализ на компонента. Простите компоненти без състояние (stateless) се превеждат първи — те тривиално се заменят с функции. След това — компоненти с едно-две полета за състояние, където useState директно заменя this.state и this.setState.

Сложните компоненти с множество методи на жизнения цикъл се превеждат чрез useEffect. Логиката от componentDidMount + componentDidUpdate се разделя на отделни useEffect с различни зависимости. componentWillUnmount се заменя с функция за връщане вътре в useEffect. За сложна логика на състоянието използвайте useReducer.

Инструментите за автоматична миграция — @phenomnomnominal/ts-react-class-to-hook или codemod скриптове — могат автоматично да конвертират прости класове. За сложни случаи миграцията остава ръчна работа, изискваща разбиране на логиката на оригиналния компонент.

Често задавани въпроси

Задължително ли е извикването на super(props) в конструктора?

Да. super(props) предава props на родителския React.Component. Без това извикване, this.props ще бъде undefined вътре в конструктора. В render и методите на жизнения цикъл, props са достъпни дори без super, но това е страничен ефект на имплементацията.

Защо setState е асинхронен?

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

Могат ли да се използват hooks вътре в класов компонент?

Не. Hooks работят само във функционални компоненти. За проекти с класови компоненти са достъпни всички стари модели: render props, HOC и Consumer за контекст. Миграцията към hooks изисква преобразуване на класа във функция.

Какво е PureComponent и как се различава от Component?

React.PureComponent имплементира shouldComponentUpdate с плитко (shallow) сравнение на props и състояние. За разлика от Component, който винаги пренарежда при setState, PureComponent пропуска пренареждането, ако данните не са се променили. Това е оптимизация за компоненти без сложно влагане.

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

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

Обобщение

  • React.Component — основен клас за компоненти с наследяване, състояние и методи на жизнения цикъл.
  • this.state се инициализира в конструктора, актуализира се само чрез this.setState — директната мутация е забранена.
  • componentDidMount — основното място за API заявки, абонаменти и таймери след първото рендериране.
  • componentWillUnmount — задължително почистване на абонаменти и таймери за предотвратяване на изтичане на памет.
  • Обвързването на this е задължително: bind в конструктора — препоръчителният начин за callback методи.
  • Hooks замениха класовите компоненти за нови проекти, но класовете остават напълно поддържани.
  • Миграцията към hooks се изпълнява постепенно: първо stateless компоненти, сложните — чрез useReducer и useEffect.

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

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също