React.Component è la classe base per creare componenti usando l'ereditarietà in React. Prima dell'introduzione degli hook nella versione 16.8, i componenti di classe erano l'unico modo per gestire stato e ciclo di vita. Secondo React, 2024, i componenti di classe sono ancora supportati, sebbene i componenti funzionali con hook siano raccomandati per i nuovi progetti.
Punti chiave
React.Component è una classe astratta che fornisce metodi integrati per lavorare con stato, props e ciclo di vita del componente. Per creare un componente di classe, devi definire una classe che estende React.Component e implementare il metodo render.
React.Component è apparso nella primissima versione di React (2013) ed è rimasto il metodo principale per creare componenti per cinque anni. L'ecosistema React è stato costruito attorno alle classi: componenti di ordine superiore (HOC), render props, contesto — tutti questi pattern sono stati implementati usando la sintassi delle classi.
Con il rilascio di React 16.8 nel 2019, il team di React ha introdotto gli hook come alternativa alle classi. Gli hook risolvevano gli stessi problemi — stato, effetti, contesto — ma senza ereditarietà e complesso binding del contesto. React.Component rimane completamente supportato, ma l'approccio funzionale è raccomandato per i nuovi progetti.
Il componente di classe minimo è una classe con un singolo metodo render che restituisce un elemento React. render è l'unico metodo obbligatorio. Deve essere una funzione pura di this.props e this.state: lo stesso insieme di props e stato produce lo stesso risultato.
import React, { Component } from 'react';
class Welcome extends Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
Il costruttore viene eseguito prima del montaggio. Chiama super(props) per passare le props alla classe genitore e inizializza this.state. Usare il costruttore per altri scopi — sottoscrizioni, chiamate API — non è raccomandato; a questo serve componentDidMount.
class Counter extends Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
render() {
return <p>Count: {this.state.count}</p>;
}
}
this.state è un oggetto contenente i dati del componente. Mutarlo direttamente (this.state.count = 1) è vietato — non attiva un re-render e rompe la prevedibilità. Lo stato deve essere aggiornato tramite this.setState, che crea un nuovo oggetto stato e attiva un re-render.
setState può accettare un oggetto o una funzione. La forma funzionale è preferita quando il nuovo stato dipende dal precedente: this.setState(prev => ({ count: prev.count + 1 })). React può raggruppare più chiamate setState in un unico lotto per ottimizzare le prestazioni.
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>
);
}
}
Una proprietà importante di setState è che è asincrono. Dopo aver chiamato setState, lo stato non viene aggiornato immediatamente. Se devi eseguire un'azione dopo l'aggiornamento, passa un callback come secondo argomento: this.setState(newState, () => console.log(this.state)).
I componenti di classe hanno metodi predefiniti che React chiama in momenti specifici. Montaggio — constructor → render → componentDidMount. Aggiornamento — render → componentDidUpdate. Smontaggio — componentWillUnmount.
| Metodo | Fase | Scopo |
|---|---|---|
| constructor | Montaggio | Inizializzare stato e bindare metodi |
| render | Ogni volta | Restituire elementi React (obbligatorio) |
| componentDidMount | Dopo montaggio | Richieste API, sottoscrizioni, timer |
| componentDidUpdate | Dopo aggiornamento | Reagire a cambiamenti di props/stato |
| componentWillUnmount | Prima della rimozione | Pulire sottoscrizioni, timer, listener eventi |
componentDidMount è il luogo principale per gli effetti collaterali dopo il primo render. Qui si eseguono richieste HTTP, si stabiliscono connessioni WebSocket e si avviano timer. Se non pulisci la sottoscrizione in componentWillUnmount, si verifica una perdita di memoria.
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>;
}
}
In JavaScript, i metodi di classe non sono legati all'istanza per impostazione predefinita. Se passi un metodo come callback — a un gestore di eventi, a un timer — this sarà undefined (in modalità strict) o window (senza modalità strict). Senza binding, this.setState lancerà un errore.
Ci sono tre modi per fare il binding: bind nel costruttore, una arrow function nel callback e un class field con arrow function. Il primo metodo è la raccomandazione ufficiale di React: bindare una volta nel costruttore, senza ricreare la funzione a ogni render.
// 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 fields — sintassi moderna con binding automatico. Un'arrow function in una proprietà di classe cattura this dallo scopo del costruttore. Lo svantaggio è che il metodo viene creato su ogni istanza, non sul prototipo, aumentando l'utilizzo di memoria per centinaia di componenti dello stesso tipo.
La scelta tra classe e funzione non è solo una questione di sintassi. I componenti funzionali con hook risolvono problemi inerenti alle classi: duplicazione della logica in diversi metodi del ciclo di vita (componentDidMount + componentDidUpdate), complessità con this e incapacità di estrarre logica correlata in un blocco riutilizzabile.
I componenti funzionali sono più facili da testare — non hanno stato interno (che prima degli hook era disponibile solo nelle classi) e non richiedono montaggio nel DOM per verificare i callback. React raccomanda componenti funzionali per tutti i nuovi progetti; la documentazione e gli esempi sono scritti con essi.
I componenti di classe rimangono la scelta migliore quando si lavora con codice legacy. Se un progetto è stato avviato prima del 2019, probabilmente contiene migliaia di componenti di classe. Riscriverli tutti in hook in un unico sprint è rischioso. React garantisce la retrocompatibilità: i componenti di classe non verranno rimossi.
La migrazione graduale inizia con l'analisi del componente. I componenti semplici senza stato vengono tradotti per primi — sono trivialmente sostituiti da funzioni. Poi — componenti con uno o due campi di stato, dove useState sostituisce direttamente this.state e this.setState.
I componenti complessi con molteplici metodi del ciclo di vita vengono tradotti usando useEffect. La logica da componentDidMount + componentDidUpdate viene suddivisa in chiamate useEffect separate con diverse dipendenze. componentWillUnmount viene sostituito da una funzione di ritorno all'interno di useEffect. Per logica di stato complessa, usa useReducer.
Gli strumenti di migrazione automatica — @phenomnomnominal/ts-react-class-to-hook o script codemod — possono convertire automaticamente le classi semplici. Per i casi complessi, la migrazione rimane un lavoro manuale che richiede la comprensione della logica del componente originale.
Domande frequenti
Sì. super(props) passa le props al React.Component genitore. Senza questa chiamata, this.props sarà undefined all'interno del costruttore. In render e nei metodi del ciclo di vita, le props sono disponibili anche senza super, ma questo è un comportamento incidentale dell'implementazione.
React raggruppa più chiamate setState in un unico lotto per ridurre i re-render non necessari. Se setState fosse sincrono, ogni chiamata attiverebbe un render immediato, riducendo le prestazioni durante gli aggiornamenti di massa.
No. Gli hook funzionano solo nei componenti funzionali. Per i progetti con componenti di classe, tutti i vecchi pattern sono disponibili: render props, HOC e Consumer per il contesto. Migrare agli hook richiede la conversione della classe in una funzione.
React.PureComponent implementa shouldComponentUpdate con un confronto superficiale di props e stato. A differenza di Component, che esegue sempre il re-render con setState, PureComponent salta il re-render se i dati non sono cambiati. È un'ottimizzazione per componenti senza annidamento complesso.
Usa componentDidCatch e getDerivedStateFromError. componentDidCatch(error, info) registra l'errore. getDerivedStateFromError aggiorna lo stato per mostrare un'interfaccia di fallback. Questi metodi funzionano solo nei componenti di classe — le funzioni necessitano di un componente ErrorBoundary wrapper.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche