Se pensi di non saperne ancora abbastanza su ReactJS sappi che questo è solo uno degli articoli di una guida più grande: ReactJS: come creare una web app da zero.
Sei pronto? Vediamo cosa è il lifecycle di ReactJS.
I metodi del Lifecycle
Ogni volta che creiamo una classe che estende React.Component possiamo fare l’override di alcuni metodi. Questi metodi fanno parte del concetto di lifecycle di ReactJS ed hanno lo scopo di gestire il ciclo di vita di un componente React. Normalmente, l’unico metodo del lifecycle che utilizzeremo sempre è il metodo render.
Gli altri metodi che influenzano il ciclo di vita di un componente cominciano con will quando precedono un evento e con did quando seguono un evento.
Quali sono i metodi del lifecycle?
I metodi del lifecycle possiamo dividerli in metodi relativi al montaggio (mount) del componente, all’aggiornamento (update) del componente ed infine allo smontaggio (unmount) del componente.
Un React.Component nel suo ciclo di vita esegue in ordine:
- Fase di Mounting
- constructor()
- componentWillMount
- render()
- componentDidMount()
- Fase di Update
- componentWillReceiveProps()
- shouldComponentUpdate()
- componentWillUpdate()
- render()
- componentDidUpdate()
- Fase di Unmounting
- componentWillUnmount()
Cos’è lo State?
Prima di poterti descrivere cosa fanno questi metodi vorrei raccontarti anche cosa è lo stato (state) di un componente ReactJS.
Lo state di un componente è un oggetto particolare nel quale gestiamo lo stato. Lo stato di un componente è definito dal valore delle proprietà dell’oggetto state. Di conseguenza ReactJS in ogni componente va ad ascoltare i cambiamenti di stato per stimolare la chiamata al metodo render.
Supponiamo di avere un componente che al click di un bottone deve far comparire una modale. Per farlo al click del bottone dovremo andare a modificare lo state del componente. Immagina di avere nello state la proprietà modaleVisibile con valore false di default. Al click andrai a cambiare il valore di modaleVisibile a true. Il metodo render verrà richiamato e avrà la logica per dire: “se il valore modaleVisibile dello state è true mostra la modale”.
Alcune Note Importanti sullo state
Lo state bisogna utilizzarlo seguendo alcune regole importanti definite da React:
- Non modificare lo state direttamente
Quindi non fare this.state.modaleVisibile = true; . Devi utilizzare la funzione setState per effettuare modifiche allo state di un componente. Scriverai quindi this.setState({modaleVisibile:true});. Solo chiamando setState verrà chiamato il metodo render per eseguire il (così chiamato) re-render - Lo state va sempre valorizzato nel costruttore ed è l’unico posto dove modificherai lo state direttamente e quindi senza uso di setState
- Quando utilizzi props e state insieme ricordati che vengono aggiornati in maniera asincrona
- Quando chiami setState puoi chiamarlo anche solo sulle proprietà dello stato che ti interessano, alla fine lo state subirà il merge (le proprietà non modificate rimarranno com’erano e verranno modificate solo le proprietà che hanno subito la modifica)
Vediamo nella pratica lo state
Per prima cosa apri il file App.js del progettino React che stai portando avanti. Posizionati con il terminale nel progetto e fallo partire (npm start). Dunque andiamo ad aggiungere un bottone che al click mostrerà un messaggio all’utente.
Il codice di partenza è questo:
Ora aggiungiamo un bottone sotto la scritta e definiamo lo state nel constructor:
class App extends Component { constructor(props){ super(props); this.state = { isTextVisible: false }; } render() { return ( <div className="App"> <div className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h2>Grazie per avermi seguito :) - Paolo Dell'Aguzzo :)</h2> </div> <p className="App-intro"> Iscriviti alla Newsletter per non perderti nulla su ReactJS e su questa guida! </p> <button className = "btn btn-primary" style={{width:"200px", height:"200px"}}> Mostra Testo </button> </div> ); } } export default App;
A questo punto è necessario creare una funzione in risposta all’evento di click sul bottone che vada a modificare lo state tramite setState:
class App extends Component { constructor(props){ super(props); this.state = { isTextVisible: false }; } showText(){ this.setState({isTextVisible:!this.state.isTextVisible}); } render() { var textToShow = this.state.isTextVisible ? (<span>Ciao adesso mi vedi!</span>) : (<span></span>); return ( <div className="App"> <div className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h2>Grazie per avermi seguito :) - Paolo Dell'Aguzzo :)</h2> </div> <p className="App-intro"> Iscriviti alla Newsletter per non perderti nulla su ReactJS e su questa guida! </p> <button className = "btn btn-primary" style={{width:"200px", height:"200px"}} onClick={this.showText.bind(this)}> Mostra Testo </button> {textToShow} </div> ); } }
Vedremo nelle prossime lezioni con maggiore dettaglio quanto accade.
Cosa fanno i metodi del Lifecycle?
I metodi del lifecycle possono servire a prendere delle decisioni ed ad effettuare modifiche al componente in modo tale anche da stimolare o meno il render.
Vediamoli uno ad uno.
ComponentWillMount
Il metodo componentWillMount viene chiamato prima del render quando il componente viene montato nel DOM. Viene chiamato anche nel caso di render del server e non scatena un nuovo render se viene impostato lo state al suo interno. Questo metodo può essere utilizzato per fare chiamate agli endpoint mentre viene caricato il componente.
ComponentDidMount
Il metodo componentDidMount viene chiamato dopo il render e normalmente è utile per tutte quelle operazioni che necessitano del DOM pronto. Chiamare setState in questo metodo darà vita ad un render. Normalmente viene consigliato di utilizzate questo metodo per fare chiamate ad endpoint.
ComponentWillReceiveProps
Il metodo componentWillReceiveProps riceve in ingresso l’oggetto nextProps il quale contiene le props che stanno per arrivare al componente. Ti ricordo che le props vengono passate da componente chiamante a componente chiamato come se fossero attributi HTML. Per esempio se dovessi chiamare il componente App del nostro esempio e volessi passargli la data di oggi potrei fare: <App today = {“15/09/2017”}/> (il componente figlio potrà quindi accedere al valore di today con this.props.today).
Se è necessario aggiornare lo state del componente è possibile anche verificare cosa si vuole aggiornare in base al cambiamento delle props. All’interno di questo metodo infatti potrai confrontare i valori di this.props con nextProps.
ShouldComponentUpdate
Il metodo shouldComponentUpdate riceve in ingresso gli oggetti nextProps e nextState. Il comportamento di default di questo metodo è quello di ritornare sempre true. Ciò vuol dire che ad ogni cambiamento di stato del componente verrà chiamato un render.
Questo metodo ti dà però la possibilità di bloccare il render e di attivarlo (ritornando true) solo al verificarsi di certe condizioni. Visto che questo metodo viene chiamato ogni volta che vengono ricevute props o che si effettuano cambi di stato, in alcuni casi si potrebbe pensare di non forzare il render automatico quando i cambiamenti non sono sensibili o importanti per ciò che mostriamo nella UI.
ComponentWillUpdate
Il metodo componentWillUpdate riceve in ingresso nextProps e nextState. Viene chiamato subito prima della chiamata al metodo render e può essere utilizzato per effettuare dei cambiamenti preliminari.
Molto importante: non va cambiato mai lo state all’interno di questo metodo, così come all’interno del metodo render. Il cambiamento dello state in questo metodo può causare un ciclo infinito perché stimola, come descritto prima, la chiamata ad alcuni metodi del ciclo di vita.
ComponentDidUpdate
Il metodo componentDidUpdate riceve in ingresso prevProps e prevState. Una volta che il componente è stato aggiornato è possibile fare qualche modifica al DOM utilizzando questo metodo. React suggerisce di sfruttare questo metodo per nuove chiamate ad endpoint che si devono verificare solo una volta avvenuti cambiamenti di props e state particolari. Bisogna evitare di modificare lo state in questo metodo.
ComponentWillUnmount
Il metodo componentWillUnmount viene chiamato subito prima che il componente venga rimosso e distrutto. Solitamente è il posto migliore dove fare delle “pulizie”. Un esempio che mi viene in mente è il rimuovere i timers impostati.
Conclusioni
In questo articolo hai imparato cos’è il lifecycle seguendo abbastanza la teoria ed hai visto un piccolo cambiamento di stato di un componente. So che non vedi l’ora di iniziare con la pratica e quindi ti dirò che ci siamo! Nel prossimo articolo inizieremo a fare una bella pagina sfruttando pian piano i diversi metodi del lifecycle ed osservando tutti i comportamenti possibili.
Se vuoi rimanere aggiornato sul continuo di questa guida ti consiglio di iscriverti alla newsletter. Mando da 1 a 4 mail al mese e normalmente invio risorse gratuite e riservate solo agli iscritti. Invio anche la lista degli articoli di maggiore impatto, come questo. Se non troverai gli articoli potrai recuperarli dalla mail in questo modo ?
Per dubbi o domande non esitare a scrivermi nei commenti ?
Se ti è piaciuto l’articolo seguimi su Facebook e Twitter oppure rimani sempre aggiornato con la newsletter (da 1 a 4 mail al mese!)
Ciao, scusa se rompo ancora, ma qualcosa nel codice non va.
dopo il var textToShow qualcosa nelle parentesi o virgole non va e mi da errore.
cosi non viene letto tutto il codice sotto.
Ciao 🙂
Assicurati di aver copiato tutta la riga e di aver seguito tutti i passaggi precedenti a questo articolo.
Non ci sono errori in quella riga 😀
P.S. Chiedi pure quando vuoi senza farti problemi 🙂
HO provato ed effettivamente funziona, solo che l’editor me lo segno come errore. o meglio me lo segna come se ci fosse un errore di apici/parentesi/virgola.
Potrebbe essere solo un errore dell’editor? di codifica del testo?
Sì è possibile 🙂
Verifica di aver configurato il tuo editor correttamente dandogli la possibilità di capire ES6 o di utilizzare qualche plugin che fa lo stesso lavoro di Babel! Inoltre quando fai copia/incolla è possibile che a volte i caratteri copiati siano leggermente diversi e potrebbe essere necessario riscrivere a mano 🙂