React.Component — komponenty klasowe i jak działają

Autor: IT Sectr Opublikowano: 2026-07-04 Czas czytania: 9 min

React.Component — podstawowa klasa do tworzenia komponentów z wykorzystaniem dziedziczenia w React. Przed pojawieniem się hooków w wersji 16.8 komponenty klasowe były jedynym sposobem zarządzania stanem i cyklem życia. Według danych React, 2024, komponenty klasowe są nadal wspierane, choć funkcjonalne z hookami są zalecane dla nowych projektów.

Najważniejsze

  • React.Component — klasa bazowa, od której dziedziczą komponenty klasowe przez extends Component.
  • Stan jest zarządzany przez this.state i aktualizowany tylko przez this.setState — bezpośrednia mutacja jest zabroniona.
  • Cykl życia obejmuje metody componentDidMount, componentDidUpdate i componentWillUnmount.
  • this w metodach klasy wymaga wiązania kontekstu — przez bind, funkcje strzałkowe lub class fields.
  • Migracja na komponenty funkcjonalne jest możliwa stopniowo: hooki i klasy mogą współistnieć w jednym projekcie.

Czym jest React.Component?

React.Component — abstrakcyjna klasa, która udostępnia wbudowane metody do pracy ze stanem, propsami i cyklem życia komponentu. Aby utworzyć komponent klasowy, należy zdefiniować klasę dziedziczącą po React.Component i zaimplementować metodę render.

React.Component pojawił się w pierwszej wersji React (2013) i pozostawał głównym sposobem tworzenia komponentów przez pięć lat. Ekosystem React budował się wokół klas: komponenty wyższego rzędu (HOC), render props, kontekst — wszystkie te wzorce zostały zaimplementowane przez składnię klasową.

Wraz z wydaniem React 16.8 w 2019 roku zespół React przedstawił hooki jako alternatywę dla klas. Hooki rozwiązywały te same zadania — stan, efekty, kontekst — ale bez dziedziczenia i skomplikowanego wiązania kontekstu. React.Component pozostaje w pełni wspierany, ale dla nowych projektów zalecane jest podejście funkcjonalne.

Tworzenie komponentu klasowego

Minimalny komponent klasowy — klasa z jedyną metodą render, zwracającą element React. render — jedyna obowiązkowa metoda. Powinna być czystą funkcją od this.props i this.state: ten sam zestaw propsów i stanu daje ten sam wynik.

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

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

Konstruktor i inicjalizacja stanu

Konstruktor jest wykonywany przed montowaniem. W nim wywoływane jest super(props) w celu przekazania propsów do klasy nadrzędnej i inicjalizowany jest this.state. Używanie konstruktora do innych celów — subskrypcji, wywołań API — nie jest zalecane: do tego służy componentDidMount.

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

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

Zarządzanie stanem przez this.state i this.setState

this.state — obiekt zawierający dane komponentu. Zmienianie go bezpośrednio (this.state.count = 1) jest zabronione — nie wywołuje to ponownego renderowania i łamie przewidywalność. Aktualizować stan należy przez this.setState, który tworzy nowy obiekt stanu i uruchamia ponowne renderowanie.

setState może przyjmować obiekt lub funkcję. Forma funkcyjna jest preferowana, gdy nowy stan zależy od poprzedniego: this.setState(prev => ({ count: prev.count + 1 })). React może grupować wiele setState w jeden batch w celu optymalizacji wydajności.

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

Ważna właściwość setState — jest asynchroniczny. Po wywołaniu setState stan nie aktualizuje się natychmiast. Jeśli trzeba wykonać działanie po aktualizacji, przekaż callback jako drugi argument: this.setState(newState, () => console.log(this.state)).

Metody cyklu życia

Komponenty klasowe mają predefiniowane metody, które React wywołuje w określonych momentach. Montowanie — constructor → render → componentDidMount. Aktualizacja — render → componentDidUpdate. Odmontowanie — componentWillUnmount.

MetodaFazaPrzeznaczenie
constructorMontowanieInicjalizacja state i wiązanie metod
renderZa każdym razemZwracanie elementów React (obowiązkowe)
componentDidMountPo montowaniuZapytania API, subskrypcje, timery
componentDidUpdatePo aktualizacjiReakcja na zmianę propsów/stanu
componentWillUnmountPrzed usunięciemCzyszczenie subskrypcji, timerów, wypisywanie się z zdarzeń

ComponentDidMount — pobieranie danych

componentDidMount — główne miejsce dla efektów ubocznych po pierwszym renderowaniu. Tutaj wykonywane są żądania HTTP, nawiązywane połączenia WebSocket i uruchamiane timery. Jeśli nie wyczyścisz subskrypcji w componentWillUnmount, wystąpi wyciek pamięci.

js
class UserProfile extends Component {
  componentDidMount() {
    fetch(`/api/users/${this.props.userId}`)
      .then(res => res.json())
      .then(data => this.setState({ user: data }));
  }

  componentWillUnmount() {
    // Anuluj żądanie przy odmontowaniu
  }

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

Wiązanie kontekstu this w metodach

W JavaScript metody klasy domyślnie nie są związane z instancją. Jeśli przekażesz metodę jako callback — do obsługi zdarzenia, timera — this będzie undefined (w trybie strict) lub window (bez trybu strict). Bez wiązania this.setState wyrzuci błąd.

Istnieją trzy sposoby wiązania: bind w konstruktorze, funkcja strzałkowa w callbacku i class field z funkcją strzałkową. Pierwszy sposób to oficjalne zalecenie React: bind raz w konstruktorze, bez ponownego tworzenia funkcji przy każdym renderowaniu.

js
// Metoda 1: bind w konstruktorze (zalecane)
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 — nowoczesna składnia z automatycznym wiązaniem. Funkcja strzałkowa we właściwości klasy przechwytuje this z zakresu widoczności konstruktora. Wadą jest to, że metoda jest tworzona na każdej instancji, a nie na prototypie, co zwiększa pamięć dla setek komponentów tego samego typu.

Porównanie komponentów klasowych i funkcjonalnych

Wybór między klasą a funkcją — to nie tylko kwestia składni. Komponenty funkcjonalne z hookami rozwiązują problemy właściwe klasom: powielanie logiki w różnych metodach cyklu życia (componentDidMount + componentDidUpdate), złożoność z this i niemożność wyodrębnienia powiązanej logiki do wielokrotnego użytku.

Komponenty funkcjonalne są łatwiejsze w testowaniu — nie mają wewnętrznego stanu (który przed hookami był tylko w klasach) i nie wymagają montowania w DOM do sprawdzania callbacków. React zaleca komponenty funkcjonalne dla wszystkich nowych projektów, dokumentacja i przykłady są pisane na nich.

Komponenty klasowe pozostają najlepszym wyborem przy pracy z starszym kodem. Jeśli projekt został rozpoczęty przed 2019 rokiem, prawdopodobnie zawiera tysiące komponentów klasowych. Przepisywanie ich wszystkich na hooki w jednym sprincie jest ryzykowne. React gwarantuje wsteczną zgodność: komponenty klasowe nie zostaną usunięte.

Strategia migracji z klas na hooki

Stopniowa migracja zaczyna się od analizy komponentu. Proste komponenty bez stanu (stateless) są tłumaczone jako pierwsze — trywialnie zastępuje się je funkcjami. Następnie — komponenty z jednym-dwoma polami stanu, gdzie useState bezpośrednio zastępuje this.state i this.setState.

Złożone komponenty z wieloma metodami cyklu życia są tłumaczone przez useEffect. Logika z componentDidMount + componentDidUpdate jest dzielona na osobne useEffect z różnymi zależnościami. componentWillUnmount jest zastępowany funkcją zwracaną wewnątrz useEffect. Do złożonej logiki stanu używaj useReducer.

Narzędzia automatycznej migracji — @phenomnomnominal/ts-react-class-to-hook lub skrypty codemod — mogą automatycznie konwertować proste klasy. W skomplikowanych przypadkach migracja pozostaje ręczną pracą, wymagającą zrozumienia logiki oryginalnego komponentu.

Często zadawane pytania

Czy wywołanie super(props) w konstruktorze jest obowiązkowe?

Tak. super(props) przekazuje propsy do nadrzędnego React.Component. Bez tego wywołania this.props będzie undefined wewnątrz konstruktora. W render i metodach cyklu życia propsy są dostępne nawet bez super, ale to efekt uboczny implementacji.

Dlaczego setState jest asynchroniczny?

React grupuje wiele wywołań setState w jeden batch w celu zmniejszenia liczby niepotrzebnych ponownych renderowań. Gdyby setState był synchroniczny, każde wywołanie powodowałoby natychmiastowe renderowanie, obniżając wydajność przy masowych aktualizacjach.

Czy można używać hooków wewnątrz komponentu klasowego?

Nie. Hooki działają tylko w komponentach funkcjonalnych. Dla projektów z komponentami klasowymi dostępne są wszystkie stare wzorce: render props, HOC i Consumer dla kontekstu. Migracja na hooki wymaga przekształcenia klasy w funkcję.

Czym jest PureComponent i czym różni się od Component?

React.PureComponent implementuje shouldComponentUpdate z płytkim (shallow) porównaniem propsów i stanu. W przeciwieństwie do Component, który zawsze przerenderowuje przy setState, PureComponent pomija przerenderowanie, jeśli dane się nie zmieniły. Jest to optymalizacja dla komponentów bez złożonego zagnieżdżenia.

Jak obsłużyć błąd w komponencie klasowym?

Użyj componentDidCatch i getDerivedStateFromError. componentDidCatch(error, info) loguje błąd. getDerivedStateFromError aktualizuje state do wyświetlenia fallback-UI. Te metody działają tylko w komponentach klasowych — funkcje potrzebują opakowującego komponentu ErrorBoundary.

Podsumowanie

  • React.Component — klasa bazowa dla komponentów z dziedziczeniem, stanem i metodami cyklu życia.
  • this.state jest inicjalizowany w konstruktorze, aktualizowany tylko przez this.setState — bezpośrednia mutacja jest zabroniona.
  • componentDidMount — główne miejsce dla zapytań API, subskrypcji i timerów po pierwszym renderowaniu.
  • componentWillUnmount — obowiązkowe czyszczenie subskrypcji i timerów w celu zapobiegania wyciekom pamięci.
  • Wiązanie this jest obowiązkowe: bind w konstruktorze — zalecany sposób dla metod-callbacków.
  • Hooki zastąpiły komponenty klasowe dla nowych projektów, ale klasy pozostają w pełni wspierane.
  • Migracja na hooki jest wykonywana stopniowo: komponenty stateless w pierwszej kolejności, złożone — przez useReducer i useEffect.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również