React.Component
These docs are old and won’t be updated. Go to react.dev for the new React docs.
These new documentation pages teach modern React:
Questa pagina contiene un riferimento dettagliato delle API della definizione della classe componente React. Viene dato per scontato che ti siano familiari i concetti fondamentali di React, come Componenti e Props, così come State e Lifecycle. Se non è così, studiali prima di proseguire.
Panoramica
React ti consente di definire componenti come classi o come funzioni. I componenti definiti come classi attualmente sono dotati di più funzionalità, che sono descritte dettagliatamente in questa pagina. Per definire una classe componente React, devi estendere React.Component:
class Benvenuto extends React.Component {
render() {
return <h1>Ciao, {this.props.nome}</h1>;
}
}L’unico metodo che è obbligatorio definire in una sottoclasse React.Component è chiamato render(). Tutti gli altri metodi descritti in questa pagina sono opzionali.
Ti sconsigliamo vivamente di creare altre classi base per i tuoi componenti. In React, il riutilizzo del codice è ottenuto soprattutto utilizzando la composizione e non l’ereditarietà.
Nota:
React non ti obbliga ad utilizzare la sintassi delle classi ES6. Se preferisci evitarla, puoi utilizzare il modulo
create-react-classo un’astrazione simile. Dai un’occhiata a React senza ES6 per saperne di più.
Il Lifecycle del Componente
Ogni componente ha numerosi “metodi del lifecycle” (metodi del ciclo di vita) che puoi sovrascrivere per eseguire del codice in momenti particolari nel processo. Puoi utilizzare questo diagramma del lifecycle come riferimento. Nella lista più in basso, i metodi del lifecycle più frequentemente utilizzati sono evidenziati in grassetto. Gli altri metodi non evidenziati esistono per casi d’uso relativamente rari.
Mounting (Montaggio)
Quando un’istanza di un componente viene creata e inserita nel DOM, questi metodi vengono chiamati nel seguente ordine:
Nota:
Questo metodo è considerato obsoleto e dovresti evitare di utilizzarlo quando scrivi del nuovo codice:
Aggiornamento
Un aggiornamento può essere causato da cambiamenti alle props o allo state. Quando un componente viene ri-renderizzato, questi metodi sono chiamati nel seguente ordine:
static getDerivedStateFromProps()shouldComponentUpdate()render()getSnapshotBeforeUpdate()componentDidUpdate()
Nota:
Questi metodi sono considerati obsoleti e dovresti evitare di utilizzarli quando scrivi del nuovo codice:
Unmounting (Smontaggio)
Quando un componente viene rimosso dal DOM, viene chiamato questo metodo:
Gestione degli Errori
Quando si verifica un errore durante la renderizzazione, in un metodo del lifecycle o nel costruttore di un componente figlio, vengono chiamati questi metodi:
Altre API
Ciascun componente fornisce anche altre API:
Proprietà della Classe
Proprietà dell’Istanza
Riferimenti
Metodi del Lifecycle Utilizzati Frequentemente
I metodi in questa sezione coprono la maggior parte dei casi d’uso che incontrerai durante la creazione di componenti React. Come riferimento grafico, puoi utilizzare questo diagramma del lifecycle.
render()
render()Il metodo render() è l’unico metodo obbligatorio in un componente classe.
Il suo compito è esaminare this.props e this.state e restituire in output uno dei seguenti tipi:
- Elementi React. Creati solitamente utilizzando JSX. Ad esempio,
<div />e<MyComponent />sono elementi React che indicano a React di renderizzare rispettivamente un nodo del DOM e un altro componente definito dall’utente. - Array e “fragments” (frammenti). Ti consentono di restituire in output più di un elemento. Leggi la documentazione sui fragments per maggiori informazioni.
- Portali. Ti consentono di renderizzare i figli del componente in un sottoalbero del DOM diverso da quello in cui si trova il componente. Leggi la documentazione sui portali per maggiori informazioni.
- Stringhe e numeri. Sono renderizzati come nodi di testo nel DOM.
- Booleani o
null. Non renderizzano niente. (Esistono soprattutto per supportare il patternreturn test && <Figlio />, in cuitestè booleano.)
La funzione render() deve essere pura, ovvero non modificare lo stato del componente, restituire sempre lo stesso risultato ogni volta che viene invocata e non interagire direttamente con il browser.
Se hai bisogno di interagire con il browser, fallo all’interno del metodo componentDidMount() o negli altri metodi del lifecycle. Mantenere pura la funzione render() rende più semplice la gestione dei componenti.
Nota
render()non viene chiamato seshouldComponentUpdate()ritorna un valore falso.
constructor()
constructor(props)Se non hai bisogno di inizializzare lo stato del componente e di non effettuare il bind di metodi, non c’è bisogno di implementare un costruttore per il tuo componente React.
Il costruttore di un componente React è chiamato prima che il componente venga montato. Quando implementi il costruttore in una sottoclasse di React.Component, dovresti chiamare super(props) prima di ogni altra istruzione. In caso contrario, this.props rimarrebbe undefined nel costruttore, il che può causare bug.
Di solito in React i costruttori sono utilizzati solamente per due scopi:
- Inizializzare lo stato locale assegnando un oggetto a
this.state. - Effettuare il bind dei gestori di eventi (event handlers) ad una istanza.
Non dovresti chiamare setState() nel constructor(). Al contrario, se il tuo componente ha bisogno di impostare lo stato locale, assegna lo stato iniziale a this.state direttamente nel costruttore:
constructor(props) {
super(props);
// Non chiamre this.setState() qui!
this.state = { contatore: 0 };
this.gestoreClick = this.gestoreClick.bind(this);
}Il costruttore è l’unico punto in cui puoi assegnare direttamente un valore a this.state. In tutti gli altri metodi, devi invece utilizzare this.setState().
Evita di introdurre i cosiddetti “side-effects” (effetti collaterali) o di effettuare sottoscrizioni nel costruttore. Per questi casi d’uso, utilizza invece componentDidMount().
Nota
Evita di copiare le props nello stato! Questo è un errore comune:
constructor(props) { super(props); // Non fare così! this.state = { colore: props.colore }; }Il problema è che questa soluzione non solo è superflua (puoi utilizzare direttamente
this.props.colore) ma è anche causa di bug (gli aggiornamenti alla propcolorenon verranno propagati allo stato, contrariamente a quanto si potrebbe erroneamente pensare).Utilizza questo pattern solamente se vuoi intenzionalmente ignorare gli aggiornamenti delle props. In quel caso, però, per rendere più comprensibile il codice ha senso rinominare la prop e chiamarla
coloreInizialeocoloreDefault. A quel punto puoi costringere un componente a “resettare” il suo stato interno cambiandone lakeyquando necessario.Leggi il post del blog a proposito di come evitare lo stato derivato per sapere cosa fare quando pensi di aver bisogno di far dipendere parti dello stato di un componente dalle sue props.
componentDidMount()
componentDidMount()componentDidMount() è invocato dopo che il componente è montato (cioè inserito nell’albero del DOM). Le logiche di inizializzazione che dipendono dai nodi del DOM dovrebbero essere dichiarate in questo metodo. Inoltre, se hai bisogno di caricare dei dati chiamando un endpoint remoto, questo è un buon punto per istanziare la chiamata.
Questo metodo è anche un buon punto in cui creare le sottoscrizioni. Se lo fai, non scordarti di cancellare in componentWillUnmount() tutte le sottoscrizioni create.
Puoi chiamare setState() immediatamente in componentDidMount(). Farlo scatenerà una richiesta di rendering aggiuntiva, che però verrà gestita prima che il browser aggiorni lo schermo. Questo garantisce che l’utente non visualizzi lo stato intermedio anche se il metodo render() viene chiamato due volte. Utilizza questo pattern con cautela in quanto spesso causa problemi di performance. Nella maggior parte dei casi, dovresti poter assegnare lo stato iniziale del componente nel constructor(). Tuttavia, potrebbe essere necessario utilizzare questo pattern in casi come i popup o i tooltip, in cui hai bisogno di misurare un nodo del DOM prima di renderizzare qualcosa che dipende dalla sua posizione o dalle sue dimensioni.
componentDidUpdate()
componentDidUpdate(propsPrecedenti, statePrecedente, snapshot)componentDidUpdate() è invocato immediatamente dopo che avviene un aggiornamento del componente. Non viene chiamato per la renderizzazione iniziale.
Utilizza questo metodo come un’opportunità di effettuare operazioni sul DOM dopo che il componente si è aggiornato, oppure per effettuare richieste di rete dopo aver comparato i valori attuali delle props con quelli passati (e.g. una richiesta di rete potrebbe non essere necessaria se le props non sono cambiate).
componentDidUpdate(propsPrecedenti) {
// Utilizzo tipico (non dimenticarti di comparare le props):
if (this.props.idUtente !== propsPrecedenti.idUtente) {
this.fetchData(this.props.idUtente);
}
}Puoi chiamare setState() immediatamente in componentDidUpdate() ma nota che la chiamata deve sempre essere subordinata a un’espressione condizionale come nell’esempio in alto, altrimenti causerai un loop infinito e una renderizzazione extra che, anche se non visibile dall’utente, può peggiorare la performance del componente. Se la tua intenzione è quella di “rispecchiare” nello stato una prop che viene dall’alto, valuta invece di utilizzare direttamente quella prop. Per saperne di più, leggi perché copiare le props nello stato è fonte di bug.
Se il tuo componente implementa il metodo del lifecycle getSnapshotBeforeUpdate() (il che avviene raramente), il valore restituito da quest’ultimo verrà passato come terzo argomento (“snapshot” nell’esempio in alto) al metodo componentDidUpdate(). In caso contrario, “snapshot” sarà undefined.
Nota
componentDidUpdate()non viene chiamato seshouldComponentUpdate()restituisce un valore falso.
componentWillUnmount()
componentWillUnmount()componentWillUnmount() è invocato subito prima che un componente sia smontato e distrutto. Effettua tutte le necessarie operazioni di pulizia in questo metodo, come la cancellazione di timer, richieste di rete o sottoscrizioni che avevi creato in componentDidMount().
Non dovresti chiamare setState() in componentWillUnmount() perché il componente non verrà ri-renderizzato. Una volta che un’istanza di un componente è smontata, non verrà mai più montata.
Metodi del Lifecycle Utilizzati Raramente
I metodi in questa sezione corrispondono a casi d’uso non comuni. Possono tornare utili qualche volta, ma la maggior parte dei tuoi componenti non dovrebbe averne bisogno. Puoi visualizzare la maggior parte dei metodi descritti in questa sezione in questo diagramma del lifecycle se spunti il checkbox “Show less common lifecycles” (“Mostra i metodi del lifecycle meno comuni”) in alto.
shouldComponentUpdate()
shouldComponentUpdate(propsSuccessive, stateSuccessivo)Utilizza shouldComponentUpdate() per informare React del fatto che l’output di un componente non è influenzato dall’attuale modifica dello state o delle props. Il comportamento predefinito di React è quello di ri-renderizzare un componente ogni volta che lo stato cambia e nella stragrande maggioranza dei casi dovresti affidarti a questo comportamento.
shouldComponentUpdate() è invocato prima della renderizzazione, quando il componente sta ricevendo nuove proprietà o un nuovo stato. Il risultato di default restituito dal metodo è true. Questo metodo non è chiamato durante la renderizzazione del componente oppure quando viene utilizzato il metodo forceUpdate().
Questo metodo esiste al solo scopo di ottimizzare la performance. Non devi utilizzarlo per “prevenire” una renderizzazione, in quanto questo può essere causa di bug. Valuta se utilizzare la classe predefinita PureComponent invece di scrivere shouldComponentUpdate() a mano. PureComponent effettua una comparazione “shallow” delle props e dello state e riduce il rischio di saltare erroneamente un aggiornamento necessario.
Se sei sicuro di voler scrivere a mano il metodo, puoi comparare this.props con propsSuccessive e this.state con stateSuccessivo e restituire false per comunicare a React che l’aggiornamento può essere saltato. Nota che restituire false non impedisce ai componenti figli di essere ri-renderizzati quando il loro stato cambia.
Non raccomandiamo di effettuare comparazioni “deep” o di utilizzare JSON.stringify() in shouldComponentUpdate(). Farlo è molto inefficiente e peggiorerà sicuramente la performance del componente.
Attualmente, quando shouldComponentUpdate() restituisce false, i metodi UNSAFE_componentWillUpdate(), render(), e componentDidUpdate() non vengono invocati. In futuro, React potrebbe però considerare il risultato di shouldComponentUpdate() semplicemente come un suggerimento, e non un ordine tassativo, nel cui caso restituire false potrebbe comunque risultare in una nuova renderizzazione del componente.
static getDerivedStateFromProps()
static getDerivedStateFromProps(props, state)getDerivedStateFromProps è invocato subito prima di chiamare render, sia durante il montaggio iniziale del componente che negli aggiornamenti successivi. Dovrebbe restituire un oggetto per aggiornare lo stato, oppure null per non effettuare aggiornamenti.
Questo metodo esiste per rari casi d’uso in cui lo stato dipende da cambiamenti delle proprietà nel corso del tempo. Ad esempio, potrebbe tornare utile per implementare un componente <Transizione> che compara i suoi figli precedenti e successivi per decidere quali di essi far comparire o sparire con un’animazione.
Derivare lo stato è spesso causa di codice verboso e rende difficile la gestione dei tuoi componenti. Assicurati di familiarizzare con alternative più semplici:
- Se hai bisogno di causare un effetto collaterale (ad esempio una richiesta di dati o un’animazione) in risposta a un cambiamento nelle props, utilizza invece il metodo del lifecycle
componentDidUpdate. - Se vuoi ricalcolare alcuni dati solo quando una prop cambia, utilizza un “memoization helper” (helper di memoizzazione).
- Se vui “resettare” lo stato quando una prop cambia, valuta invece se rendere il componente completamente controllato oppure completamente non controllato con una
key.
Questo metodo non ha accesso all’istanza del componente. Se vuoi, puoi riutilizzare parti del codice di getDerivedStateFromProps() e di altri metodi di classe dichiarando, all’esterno della definizione della classe del componente, funzioni pure che accettano come argomenti le props e lo state.
Nota che questo metodo viene chiamato ogni volta che viene effettuato un render, a prescindere dalla causa. Al contrario, UNSAFE_componentWillReceiveProps viene invocato solo quando il parent causa la ri-renderizzazione e non quando quest’ultima è il risultato di una chiamata a setState all’interno del componente stesso.
getSnapshotBeforeUpdate()
getSnapshotBeforeUpdate(propsPrecedenti, statePrecedente)getSnapshotBeforeUpdate() è invocato subito prima che il più recente output della renderizzazione sia consolidato ad esempio nel DOM. Permette al tuo componente di catturare informazioni riguardo al DOM (e.g. la posizione dello scroll) prima che avvenga un potenziale cambiamento. Qualsiasi valore restituito da questo metodo del lifecycle verrà passato come parametro a componentDidUpdate().
Questo caso d’uso non è comune, ma potrebbe verificarsi in UI come i canali delle chat, che hanno bisogno di gestire la posizione dello scroll in modo speciale.
Il metodo dovrebbe restituire un valore di “snapshot” (o null).
Ad esempio:
class ListaScorrimento extends React.Component {
constructor(props) {
super(props);
this.rifLista = React.createRef();
}
getSnapshotBeforeUpdate(
propsPrecedenti,
statePrecedente
) {
// Stiamo aggiungendo nuovi elementi alla lista?
// Salviamo la posizione dello scroll in modo da poterla aggiustare in seguito.
if (
propsPrecedenti.list.length < this.props.list.length
) {
const lista = this.rifLista.current;
return lista.scrollHeight - lista.scrollTop;
}
return null;
}
componentDidUpdate(
propsPrecedenti,
statePrecedente,
snapshot
) {
// Se snapshot è definito, abbiamo appenan aggiunto nuovi elementi alla lista.
// Aggiustiamo lo scroll in modo che i nuovi elementi non spingano quelli
// preesistenti fuori dallo schermo.
// (snapshot contiene il valore restituito da getSnapshotBeforeUpdate)
if (snapshot !== null) {
const lista = this.rifLista.current;
lista.scrollTop = lista.scrollHeight - snapshot;
}
}
render() {
return (
<div ref={this.rifLista}>{/* ...contenuti... */}</div>
);
}
}
Nell’esempio qui sopra, è importante leggere la proprietà scrollHeight in getSnapshotBeforeUpdate perché potrebbero verificarsi ritardi fra i metodi del lifecycle che appartengono alla fase della renderizzazione (come render) e i metodi che appartengono alla fase del “consolidamento” (come getSnapshotBeforeUpdate e componentDidUpdate).
Contenitori di Errori
I Contenitori di Errori sono componenti React che si occupano di catturare gli errori JavaScript in qualunque punto nell’albero dei loro componenti figli, loggarli e visualizzare una UI di ripiego invece dell’albero di componenti che si è rotto. I Contenitori di Errori catturano gli errori durante la renderizzazione, nei metodi del lifecycle e nei costruttori dell’intero albero sotto di loro.
Un componente classe diventa un contenitore di errori se definisce uno (o entrambi) dei metodi del lifecycle static getDerivedStateFromError() o componentDidCatch(). Aggiornare lo stato all’interno di questi metodi del lifecycle ti consente di catturare un errore JavaScript non gestito nell’albero più in basso e mostrare una UI di ripiego.
Utilizza i contenitori di errori solamente per recuperare errori inaspettati; non utilizzarli per il controllo di flusso dell’applicazione.
Per maggiori informazioni, vedi Gestione degli Errori in React 16.
Nota
I contenitori di errori catturano solamente gli errori sollevati dai componenti sotto di loro nell’albero. Un contenitore di errori non è in grado di catturare un errore sollevato da lui stesso.
static getDerivedStateFromError()
static getDerivedStateFromError(error)Questo metodo del lifecycle è invocato dopo che un errore è stato sollevato da un componente discendente. Riceve l’errore che è stato sollevato come parametro e dovrebbe restituire un valore da usare per aggiornare lo state.
class ContenitoreErrori extends React.Component {
constructor(props) {
super(props);
this.state = { inErrore: false };
}
static getDerivedStateFromError(error) { // Aggiorno lo stato in modo che il prossimo render visualizzi la UI di ripiego. return { inErrore: true }; }
render() {
if (this.state.inErrore) { // Puoi renderizzare una qualsiasi interfaccia di ripiego return <h1>Oh no! Si è verificato un errore!