In questo articolo vediamo i nuovi metodi del lifecycle getDerivedStateFromProps e getSnapshotBeforeUpdate. Questi due nuovi metodi del lifecycle sono molto utili per evitare diversi possibili bug all’interno di una web app ReactJS ed inoltre sono nati come rimpiazzo ad alcuni dei metodi del lifecycle che da ReactJS 17 saranno disponibili solo come metodi non sicuri (unsafe).
Se sei quì per caso e vuoi imparare (o ripassare) ReactJS, dai un’occhiata a questa guida in italiano.
I nuovi metodi del lifecycle getDerivedStateFromProps e getSnapshotBeforeUpdate
Prima di iniziare a parlare dei nuovi metodi del lifecycle getDerivedStateFromProps e getSnapshotBeforeUpdate è necessario farti notare che i seguenti metodi sono ora presenti anche con il prefisso UNSAFE_ e che da React 17 saranno disponibili solo con prefisso UNSAFE_:
- componentWillMount
- componentWillReceiveProps
- componentWillUpdate
Essendo questi metodi spesso utilizzati in maniera sbagliata, creando anche un abuso di utilizzo dando vita a rallentamenti delle web app e visto che il team di React vuole far diventare ReactJS una libreria con render asincrono così da migliorare le performance anche su dispositivi mobili (vedi quì), sono stati “marchiati” come metodi non sicuri.
Di conseguenza sono disponibili due nuovi metodi del lifecycle che permettono di eseguire alcune computazioni in maniera molto più sicura:
- getDerivedStateFromProps
- getSnapshotBeforeUpdate
Vediamo insieme nel dettaglio i nuovi metodi del lifecycle getDerivedStateFromProps e getSnapshotBeforeUpdate.
getDerivedStateFromProps
Il metodo del lifecycle getDerivedStateFromProps nasce come alternativa sicura a componentWillReceiveProps. E’ un metodo statico e questa è la sua firma:
static getDerivedStateFromProps(props, state)
Viene invocato subito prima del render sia quando il componente viene montato sia quando il componente riceve aggiornamenti.
Il parametro props contiene le props appena lette ed il parametro state contiene lo state corrente. Ciò indica che un confronto tra vecchie e nuove props si può fare solo salvando nello state il precedente valore delle props. Un esempio preso dalla guida:
class EmailInput extends Component { state = { email: this.props.defaultEmail, prevPropsUserID: this.props.userID }; static getDerivedStateFromProps(props, state) { // Any time the current user changes, // Reset any parts of state that are tied to that user. // In this simple example, that's just the email. if (props.userID !== state.prevPropsUserID) { return { prevPropsUserID: props.userID, email: props.defaultEmail }; } return null; } // ... }
All’interno di questo metodo è possibile scrivere del codice che ritorna un oggetto per aggiornare lo state del componente oppure null per non aggiornare nulla.
Viene consigliato l’utilizzo di questo metodo in rari casi e precisamente quando lo state del componente dipende dalle props in ingresso. Viene consigliato in maniera specifica per aggiornare ad esempio le transition quando cambiano i children di un componente.
Fai attenzione! Questo metodo viene chiamato ogni volta prima del rendering al contrario di componentWillReceiveProps che veniva invocato solo quando il componente padre causava un rendering.
Per maggiori informazioni puoi leggere la guida ufficiale a questo indirizzo.
Ricorda: se hai bisogno di cambiare lo stato del componente in seguito al cambio delle props, effettuando operazioni sui dati, è consigliato eseguire queste operazioni nel metodo del lifecycle componentDidUpdate (puoi verificare in questo metodo lo stato precedente e le props precedenti, di conseguenza se le props nuove sono differenti da quelle passate esegui i calcoli necessari). Al contrario in getDerivedStateFromProps hai la necessità di verificare ogni props in base al vecchio valore, salvato nello state, per decidere se aggiornare lo stato (ciò potrebbe portare ad avere uno state enorme ed ad appesantire la web app nella fase di pre-rendering).
getSnapshotBeforeUpdate
Il metodo del lifecycle getSnapshotBeforeUpdate è stato creato invece per leggere le proprietà del DOM in maniera sicura.
Questo metodo viene invocato subito prima che il nuovo DOM venga committato, quindi può essere molto utile per scoprire, ad esempio, quale sia la scrollPosition un attimo prima che il DOM subisca modifiche (giusto un esempio tratto dalla guida ufficiale).
In getSnapshotBeforeUpdate hai la possibilità quindi di recuperare le refs in maniera sicura e puoi far ritornare un oggetto, una stringa, un numero, ecc. che sarà dunque disponibile nel metodo del lifecycle componentDidUpdate.
La firma del metodo getSnapshotBeforeUpdate è la seguente:
getSnapshotBeforeUpdate(prevProps, prevState)
La firma di componentDidUpdate diventa invece questa:
componentDidUpdate(prevProps, prevState, snapshot)
Puoi avere maggiori informazioni direttamente nella guida ufficiale a questo indirizzo.
Cosa evitare?
Quello che vogliamo offrire all’utente è un’ottima esperienza, fluida ed ottima per ogni dispositivo.
Come detto prima per getDerivedStateFromProps (vedi “Ricorda”) operazioni pesanti o lente che hanno influenza sullo state di un componente al cambio delle props è meglio eseguirle in componentDidUpdate.
Inoltre, mentre componentDidUpdate rimane il metodo più indicato per animazioni e per il recupero dei dati dagli endpoint, la computazione dei dati può essere fatta anche durante il render utilizzando la “memoization”.
Per maggiori informazioni sulla memoization ti consiglio di leggere l’ottima documentazione a questo indirizzo.
Ricordati che l’utilizzo di questi metodi è molto raro e che non dovresti abusarne. La maggior parte delle computazioni dovrebbero essere svolte in componentDidMount e componentDidUpdate. E’ piuttosto raro che un componente debba utilizzare gli altri metodi per grandi computazioni (il render ovviamente è un metodo sempre necessario).
Se ancora non ti fidi di me puoi andare quì e leggere come mai probabilmente non hai bisogno di getDerivedStateFromProps.
I nuovi metodi del lifecycle getDerivedStateFromProps e getSnapshotBeforeUpdate
Credo che hai capito come funzionano i nuovi metodi del lifecycle getDerivedStateFromProps e getSnapshotBeforeUpdate. Sono anche più che convinto del fatto che non li utilizzerai molto (rispetto agli altri metodi) e che sei un po’ spaventato nel vedere che da ReactJS 17 potrai usare componentWillReceiveProps, componentWillMount e componentWillUpdate solo con prefisso “UNSAFE_”.
Se ti può interessare puoi anche iniziare a rinominare i metodi nei tuoi vecchi progetti con uno script creato dal team di Facebook proprio per questo scopo, lo trovi quì. Ma..! Forse faresti meglio a pensare a come rimpiazzarli e a rispondere alla domanda: ne ho abusato?
Non scordarti che se hai bisogno di un ripasso su ReactJS c’è la guida per imparare ReactJS. Inoltre ho scritto anche una guida che ti insegna a creare la tua prima app per Android e iOS con React Native, la trovi quì.
Per approfondire React potrebbero esserti utili alcuni libri quali:
Ed alcuni corsi Udemy quali:
- Introduction to TypeScript DevelopmentCorso JavaScript – ES6, NodeJS, ReactJS in italiano (Lite)
- Modern React with Redux
- React 16 – The Complete Guide (incl. React Router 4 & Redux)
Se vuoi rimanere aggiornato sugli articoli del blog 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!).