Un class component è una classe JavaScript che estende React.Component e restituisce JSX da un metodo render(). Legge le props da this.props, tiene lo stato in this.state e lo aggiorna con this.setState(). I function component con gli hook li hanno sostituiti per il codice nuovo, ma le classi sono ancora pienamente supportate, compaiono in molte codebase più vecchie e sono l'unico modo per scrivere un error boundary.
Ogni contatore tiene il proprio stato. Aggiungi un terzo <Counter label="Plums" /> e parte anche lui da 0.
Anatomia di un class component
import { Component } from 'react';
class Welcome extends Component {
static defaultProps = { name: 'stranger' };
constructor(props) {
super(props); // required before using this
this.state = { visits: 1 };
}
render() {
return <h1>Hello, {this.props.name}. Visit #{this.state.visits}</h1>;
}
}
- La classe estende
Component(oReact.Componentconimport React from 'react'). render()è obbligatorio. Deve essere puro, come il corpo di un function component: leggethis.propsethis.state, restituisce JSX.this.propscontiene le props. Sono di sola lettura.- Lo stato può essere impostato in un
constructor(chiama primasuper(props)) o, più comunemente oggi, come campo della classe:state = { visits: 1 };. static defaultPropsfunziona ancora per le classi in React 19 (è stato rimosso solo per i function component).
this.setState unisce, e può ricevere una funzione di aggiornamento
setState fa due cose in modo diverso dal setter di useState. Unisce l'oggetto che passi allo stato attuale, quindi aggiorni solo le chiavi che nomini. E, come ogni aggiornamento di stato in React, non viene applicato immediatamente, quindi usa la forma con funzione di aggiornamento quando il valore successivo dipende da quello precedente.
"+3 with objects" aggiunge uno, perché tutte e tre le chiamate leggono lo stesso this.state.likes. "+3 with updaters" aggiunge tre. "Move to Paris" mantiene name e likes (l'unione) ma perde zip, perché l'unione è profonda un solo livello. Scrivi address: { ...this.state.address, city: 'Paris' } per mantenerlo. Il secondo argomento facoltativo di setState viene eseguito dopo l'aggiornamento, e la console lì mostra il nuovo indirizzo.
Binding dei gestori di eventi
Un metodo passato come onClick={this.handleClick} viene chiamato più tardi come semplice funzione, senza il suo oggetto, quindi al suo interno this è undefined.
Il primo pulsante registra un TypeError sulla lettura di setState di undefined. Il secondo funziona, perché una arrow function in un campo della classe cattura this quando viene creata l'istanza. La soluzione più vecchia, ancora comune nel codice legacy, fa il binding nel costruttore:
constructor(props) {
super(props);
this.state = { on: false };
this.handleClick = this.handleClick.bind(this);
}
Funziona anche una arrow in linea, onClick={() => this.handleClick()}.
Metodi del ciclo di vita
Le classi reagiscono a montaggio, aggiornamento e smontaggio tramite metodi con nomi fissi. Quelli che vedrai più spesso:
componentDidMount(): dopo che il primo rendering è nel DOM. Avvia timer, sottoscrizioni, richieste.componentDidUpdate(prevProps, prevState): dopo ogni aggiornamento. Confronta con i valori precedenti prima di fare qualsiasi lavoro, altrimenti entri in un ciclo.componentWillUnmount(): prima della rimozione. Annulla ciò checomponentDidMountha avviato.shouldComponentUpdate(nextProps, nextState): restituiscifalseper saltare un rendering.
La pagina sul ciclo di vita dei componenti ha la lista completa, l'ordine in cui vengono eseguiti e un componente che li registra tutti.
Convertire una classe in un function component
Ecco una classe che usa tutti e tre i metodi del ciclo di vita più comuni. Avanza ogni secondo, registra quando cambia la sua prop label e ferma il timer quando viene rimossa.
Ed ecco lo stesso componente come funzione. Ogni metodo del ciclo di vita diventa parte di un effetto, e setup e cleanup correlati stanno uno accanto all'altro invece che in due metodi.
Entrambi i timer contano allo stesso modo e registrano a ogni cambio di etichetta. La versione con funzione registra anche una volta al montaggio, perché un effetto viene eseguito anche dopo il primo rendering. I passaggi per qualsiasi conversione:
this.props.xdiventa una prop destrutturata,{ x }.- Ogni chiave di
this.statediventa il propriouseState. Ricorda che il setter sostituisce invece di unire. - I metodi diventano semplici funzioni dentro il componente. Nessun binding necessario.
componentDidMount,componentDidUpdateecomponentWillUnmountdiventano chiamate auseEffect, raggruppate per ciò che fanno invece che per quando vengono eseguite.createRefdiventauseRef, estatic contextTypeconthis.contextdiventauseContextouse.
Lascia gli error boundary come classi; non hanno un equivalente come funzione.
PureComponent
Un normale class component si renderizza ogni volta che lo fa il suo genitore. PureComponent prima confronta le nuove props e il nuovo stato con quelli precedenti, a un solo livello di profondità, e salta il rendering quando non è cambiato nulla. È la controparte per le classi di React.memo.
Clicca il pulsante: viene registrato solo PlainLabel rendered, perché PureLabel vede lo stesso text. Passa text={'hello ' + clicks} a entrambi ed entrambi si renderizzano a ogni clic.
Il confronto è superficiale, quindi una prop che è un nuovo oggetto o una nuova funzione a ogni rendering del genitore (style={{ color: 'red' }}, onClick={() => ...}) lo vanifica. È la stessa trappola di React.memo.
Cose che React 19 ha rimosso dalle classi
Se mantieni codice vecchio con classi, alcuni schemi non funzionano più in React 19:
- Ref stringa (
ref="input"conthis.refs.input). UsacreateRef()o un ref callback. - Context legacy (
contextTypes,childContextTypes,getChildContext). UsacreateContextconstatic contextType. propTypesvengono ignorati. Usa TypeScript o controlli tuoi.findDOMNodenon esiste più. Metti invece un ref sull'elemento DOM.
Anche i vecchi metodi componentWillMount, componentWillReceiveProps e componentWillUpdate sono legacy. Vengono ancora eseguiti, sia con i vecchi nomi sia con i nomi UNSAFE_ (UNSAFE_componentWillMount e così via), ma sono deprecati e StrictMode avvisa del loro uso; sposta il loro codice in componentDidMount, componentDidUpdate o getDerivedStateFromProps.
Domande frequenti
I class component sono deprecati in React?
No. Sono ancora supportati in React 19 e continueranno a funzionare, ma la documentazione di React consiglia i function component con gli hook per il codice nuovo. Ti serve ancora una classe per gli error boundary.
Qual è la differenza tra class component e function component?
Un class component tiene lo stato in this.state, lo aggiorna con this.setState e reagisce al ciclo di vita con metodi dal nome preciso. Un function component usa gli hook (useState, useEffect) per gli stessi compiti, non ha bisogno di this ed è più breve.
setState aggiorna lo stato immediatamente?
No. this.setState programma un aggiornamento e React renderizza più tardi, quindi subito dopo la chiamata this.state ha ancora il vecchio valore. Passa una funzione, this.setState((state) => ...), quando il nuovo valore dipende da quello vecchio, oppure leggi il risultato nella callback del secondo argomento o in componentDidUpdate.
Perché this è undefined nel mio gestore di eventi?
Un metodo della classe passato come onClick={this.handleClick} viene chiamato senza il suo oggetto, quindi this è undefined. Definisci il gestore come arrow function in un campo della classe (handleClick = () => { ... }) oppure fai il binding nel costruttore.
Cos'è PureComponent?
Un Component che salta il rendering quando le sue props e il suo stato sono superficialmente uguali a quelli precedenti. È la versione per le classi di React.memo.