React.Component — clasa de bază pentru crearea componentelor cu moștenire în React. Înainte de apariția hook-urilor în versiunea 16.8, componentele de clasă erau singura modalitate de a gestiona starea și ciclul de viață. Potrivit React, 2024, componentele de clasă sunt încă suportate, deși cele funcționale cu hook-uri sunt recomandate pentru proiecte noi.
Principalele puncte
React.Component — o clasă abstractă care oferă metode încorporate pentru lucrul cu starea, props-urile și ciclul de viață al componentei. Pentru a crea o componentă de clasă, trebuie să definiți o clasă care moștenește React.Component și să implementați metoda render.
React.Component a apărut în prima versiune React (2013) și a rămas principalul mod de a crea componente timp de cinci ani. Ecosistemul React s-a construit în jurul claselor: componente de ordin superior (HOC), render props, context — toate aceste pattern-uri au fost implementate prin sintaxa de clasă.
Odată cu lansarea React 16.8 în 2019, echipa React a introdus hook-urile ca alternativă la clase. Hook-urile rezolvau aceleași sarcini — stare, efecte, context — dar fără moștenire și legare complexă a contextului. React.Component rămâne complet suportat, dar pentru proiecte noi se recomandă abordarea funcțională.
O componentă de clasă minimă — o clasă cu o singură metodă render care returnează un element React. render — singura metodă obligatorie. Trebuie să fie o funcție pură de this.props și this.state: același set de props-uri și stare dă același rezultat.
import React, { Component } from 'react';
class Welcome extends Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
Constructorul se execută înainte de montare. În el se apelează super(props) pentru a transmite props-urile clasei părinte și se inițializează this.state. Utilizarea constructorului în alte scopuri — abonamente, apeluri API — nu este recomandată: pentru aceasta există componentDidMount.
class Counter extends Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
render() {
return <p>Count: {this.state.count}</p>;
}
}
this.state — obiectul care conține datele componentei. Modificarea directă (this.state.count = 1) este interzisă — nu provoacă re-rendare și strică predictibilitatea. Actualizarea stării trebuie făcută prin this.setState, care creează un nou obiect de stare și declanșează re-rendarea.
setState poate primi un obiect sau o funcție. Forma funcțională este preferată când noua stare depinde de cea anterioară: this.setState(prev => ({ count: prev.count + 1 })). React poate grupa mai multe setState într-un singur batch pentru optimizarea performanței.
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>
);
}
}
O proprietate importantă a setState — este asincron. După apelarea setState, starea nu se actualizează imediat. Dacă trebuie să executați o acțiune după actualizare, transmiteți un callback ca al doilea argument: this.setState(newState, () => console.log(this.state)).
Componentele de clasă au metode predefinite pe care React le apelează în momente specifice. Montarea — constructor → render → componentDidMount. Actualizarea — render → componentDidUpdate. Demontarea — componentWillUnmount.
| Metodă | Fază | Scop |
|---|---|---|
| constructor | Montare | Inițializarea state și legarea metodelor |
| render | De fiecare dată | Returnarea elementelor React (obligatoriu) |
| componentDidMount | După montare | Cereri API, abonamente, timer-e |
| componentDidUpdate | După actualizare | Reacție la schimbarea props-urilor/stării |
| componentWillUnmount | Înainte de ștergere | Curățarea abonamentelor, timer-elor, dezabonarea de la evenimente |
componentDidMount — locul principal pentru efecte secundare după prima randare. Aici se execută cereri HTTP, se stabilesc conexiuni WebSocket și se pornesc timer-e. Dacă nu curățați abonamentul în componentWillUnmount, apare o scurgere de memorie.
class UserProfile extends Component {
componentDidMount() {
fetch(`/api/users/${this.props.userId}`)
.then(res => res.json())
.then(data => this.setState({ user: data }));
}
componentWillUnmount() {
// Anulare cerere la demontare
}
render() {
return <div>{this.state.user?.name}</div>;
}
}
În JavaScript, metodele clasei nu sunt legate implicit de instanță. Dacă transmiteți o metodă ca callback — la un handler de eveniment, un timer — this va fi undefined (în modul strict) sau window (fără modul strict). Fără legare, this.setState va arunca o eroare.
Există trei moduri de legare: bind în constructor, funcție săgeată în callback și class field cu funcție săgeată. Prima modalitate — recomandarea oficială React: bind o dată în constructor, fără recrearea funcției la fiecare randare.
// Metoda 1: bind în constructor (recomandat)
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 — sintaxă modernă cu legare automată. Funcția săgeată în proprietatea clasei capturează this din domeniul de vizibilitate al constructorului. Dezavantajul — metoda este creată pe fiecare instanță, nu pe prototip, ceea ce crește memoria pentru sute de componente de același tip.
Alegerea între clasă și funcție — nu este doar o chestiune de sintaxă. Componentele funcționale cu hook-uri rezolvă problemele inerente claselor: duplicarea logicii în diferite metode ale ciclului de viață (componentDidMount + componentDidUpdate), complexitatea cu this și imposibilitatea extragerii logicii conexe într-un bloc reutilizabil.
Componentele funcționale sunt mai ușor de testat — nu au stare internă (care înainte de hook-uri era doar în clase) și nu necesită montarea în DOM pentru verificarea callback-urilor. React recomandă componente funcționale pentru toate proiectele noi, documentația și exemplele sunt scrise cu ele.
Componentele de clasă rămân cea mai bună alegere pentru lucrul cu cod moștenit. Dacă proiectul a fost început înainte de 2019, probabil conține mii de componente de clasă. Rescrierea tuturor în hook-uri într-un singur sprint este riscantă. React garantează compatibilitatea inversă: componentele de clasă nu vor fi eliminate.
Migrarea treptată începe cu analiza componentei. Componentele simple fără stare (stateless) sunt traduse primele — ele sunt înlocuite trivial cu funcții. Apoi — componentele cu una-două câmpuri de stare, unde useState înlocuiește direct this.state și this.setState.
Componentele complexe cu multiple metode ale ciclului de viață sunt traduse prin useEffect. Logica din componentDidMount + componentDidUpdate este împărțită în useEffect-uri separate cu dependențe diferite. componentWillUnmount este înlocuit cu o funcție returnată în interiorul useEffect. Pentru logica complexă a stării, folosiți useReducer.
Instrumentele de migrare automată — @phenomnomnominal/ts-react-class-to-hook sau scripturile codemod — pot converti automat clasele simple. Pentru cazuri complexe, migrarea rămâne o muncă manuală care necesită înțelegerea logicii componentei originale.
Întrebări frecvente
Da. super(props) transmite props-urile către React.Component părinte. Fără această apelare, this.props va fi undefined în interiorul constructorului. În render și metodele ciclului de viață, props-urile sunt accesibile chiar și fără super, dar acesta este un comportament secundar al implementării.
React grupează mai multe apeluri setState într-un singur batch pentru a reduce numărul de re-rendări inutile. Dacă setState ar fi sincron, fiecare apel ar provoca o randare imediată, reducând performanța la actualizări masive.
Nu. Hook-urile funcționează doar în componente funcționale. Pentru proiecte cu componente de clasă, sunt disponibile toate pattern-urile vechi: render props, HOC și Consumer pentru context. Migrarea la hook-uri necesită transformarea clasei într-o funcție.
React.PureComponent implementează shouldComponentUpdate cu comparare superficială (shallow) a props-urilor și stării. Spre deosebire de Component, care re-renderează întotdeauna la setState, PureComponent omite re-rendarea dacă datele nu s-au schimbat. Este o optimizare pentru componente fără imbricare complexă.
Folosiți componentDidCatch și getDerivedStateFromError. componentDidCatch(error, info) înregistrează eroarea. getDerivedStateFromError actualizează state-ul pentru afișarea unui UI de rezervă. Aceste metode funcționează doar în componentele de clasă — funcțiile au nevoie de o componentă wrapper ErrorBoundary.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și