Ti ricordo, se è la prima volta che ti imbatti in questa guida, che questo articolo fa parte di una raccolta più grande su Come Creare una Web App da Zero.
State e setState
Lo state ReactJS è un contenitore di informazioni ed è un oggetto contenente diverse proprietà.
Esattamente come un oggetto che rappresenta un utente {nome:”Paolo”, cognome”Dell’Aguzzo”}, lo state contiene tutte quelle informazioni necessarie al componente React per stabilire il render dell’interfaccia (esistono al contrario componenti senza stato che vengono utilizzati da componenti con lo stato ed utilizzano solo le props).
Come spiegato nella guida principale a questo indirizzo, lo state andrebbe manipolato ed utilizzato soltanto quando necessario per il render del componente che stiamo scrivendo.
SetState è il metodo da chiamare in grado di modificare lo state. Lo state infatti deve essere impostato all’interno del costruttore di un componente e deve essere manipolato tramite metodo setState.
Cosa ha di speciale setState?
Il metodo setState permette a ReactJS di ascoltare cambiamenti dello stato di un componente. Per questo motivo al cambio di stato vengono richiamati alcuni metodi del lifecycle tra cui il metodo render.
Se vuoi saperne di più ti ricordo che già nella guida abbiamo parlato di tutti i metodi del lifecycle in questo articolo.
Utilizziamo state e setState
So che ancora ti potrebbe sembrare arabo, ma non ti preoccupare 🙂 .
Ti ricordi l’applicazione che stiamo costruendo? Ha una pagina di login che abbiamo inserito nella scorsa lezione. Quello che vogliamo fare è una form di login con username e password. Al click sul pulsante Invio vogliamo scrivere nella console del browser quali sono lo username e la password inseriti.
In futuro utilizzeremo username e password per fare una elaborazione più grande, magari cercare se l’utente si trova in un database o altre cose simili. Al momento scriveremo solo nella console.
React Component Login
Apri il file login.js (lo abbiamo messo in components/login). Dunque sostituisci il codice presente in questo file con questo nuovo codice:
import React from "react"; export default class Login extends React.Component{ constructor(props){ super(props); this.state = { username: '', password: '' } } changeUsername(event){ this.setState({username:event.target.value}); } changePassword(event){ this.setState({password:event.target.value}); } onSubmit(event){ event.preventDefault(); } login(event){ //FAKE REST API NEI PROSSIMI ARTICOLI console.log("Login con username: ", this.state.username); console.log("Login con password: ", this.state.password); } render(){ return( <div style={{marginTop:"100px", minHeight:"70vh"}}> <div className = "container"> <div className = "row"> <div className = "col-6 mr-auto ml-auto"> <form onSubmit={this.onSubmit.bind(this)}> <div className = "form-group"> <input type="text" className = "form-control" placeholder="username" value = {this.state.username || ''} onChange = {this.changeUsername.bind(this)}/> </div> <div className = "form-group"> <input type="password" className = "form-control" placeholder="password" value = {this.state.password} onChange = {this.changePassword.bind(this)}/> </div> <button type="submit" className = "btn btn-primary pull-right" onClick={this.login.bind(this)}> Invio </button> </form> </div> </div> </div> </div> ); } }
Quello che abbiamo fatto di diverso rispetto a prima è:
- Inserire nel constructor l’inizializzazione dello state che è composto dalle proprietà username e password
- Cambiare il metodo render facendogli ritornare una form composta da 2 input ed un button
- Abbiamo messo sulla form un metodo da chiamare quando l’utente fa il submit della form, quindi in risposta all’evento di onSubmit
- Abbiamo scritto il metodo onSubmit per far sì che il submit della form non ricarichi la pagina (comportamento di default)
- Abbiamo inserito come valore degli input (attributo value) i rispettivi valori dello state. Il valore relativo all’input dello username è this.state.username, ovvero il campo username presente nello state del componente
- Abbiamo inserito per gli input di username e password un metodo che risponde all’evento di onChange. Ovvero quando l’utente digita qualcosa nell’input viene registrato un evento di onChange. Al cambio dello username risponde il metodo changeUsername che utilizza il metodo setState per aggiornare lo state del componente con i valori digitati
- Abbiamo collegato un metodo all’evento onClick del pulsante di invio dei dati. Tale metodo, chiamato login, al momento scrive nella console del browser il valore di username e password
Narrazione di state e setState
Per cercare di addolcire la pillola ti spiegherò ancora una volta quello che sta accadendo, senza essere troppo schematico.
Quando entriamo nella pagina di login il componente scritto nel file login.js viene inserito nello schermo, quindi viene renderizzato.
Come già visto studiando il lifecycle questa operazione avviene poiché React chiama in ordine una serie di metodi. Il primo tra questi è il costruttore, da lì in poi nel nostro componente login chiamerà direttamente il metodo render.
Appena viene trovato il componente Login quindi viene impostato lo state del componente dicendogli che è formato da username e password inizialmente vuoti. Dunque viene chiamato il render che mostra a schermo degli input ed un pulsante.
Gli input sono vuoti inizialmente perché lo state non riporta valori per username e password visibili nell’input. Dunque se l’utente si posiziona sullo username e digita una lettera, numero o simbolo immediatamente viene stimolato l’evento di onChange. Dunque React si accorge subito che è cambiato qualcosa e chiama il metodo che abbiamo deciso noi (per esempio changeUsername).
Ogni metodo relativo al cambio di un valore utilizza il metodo setState per cambiare lo stato. In questo modo viene stimolato un altro ciclo e viene richiamato il metodo render.
Quando React va a renderizzare gli input adesso vedremo nello username il valore digitato perché il suo value è il contenuto della proprietà username dell’oggetto state.
Miglioriamo un po’ il codice
Per essere un po’ più snelli non abbiamo bisogno di 2 metodi per gestire l’onChange dello username e l’onChange della password.
Di conseguenza possiamo cancellare i due metodi changeUsername e changePassword e sostituirli con:
changeText(field, event){ this.setState({[field]:event.target.value}); }
Come immagini adesso dobbiamo cambiare anche i metodi collegati all’evento di onChange dei 2 input.
Prendi l’input dello username e sostituisci il contenuto di onChange con:
this.changeText.bind(this, "username")
Fai la stessa cosa per l’input della password passando però al posto di “username” il valore “password”:
this.changeText.bind(this, "password")
In pratica stiamo passando al metodo changeText il valore della proprietà che vogliamo modificare all’interno dello state. Il metodo changeText è infatti generico e scrive nello stato il valore che gli arriva in input mappandolo con il campo che gli arriva in input.
Per utilizzare come proprietà di un oggetto un valore che ci arriva da una variabile utilizziamo le parentesi quadre ([field] nel nostro caso).
Perché tutti i metodi hanno il bind(this)?
Il binding è necessario per far sì che all’interno del metodo chiamato, o della funzione di callback chiamata, possiamo utilizzare this. This non sarà undefined ed oltre tutto il this che utilizzeremo sarà quello del componente che chiama il metodo (quindi possiamo chiamare this.setState()).
Conclusione
State e setState sono la chiave di ReactJS. Tramite l’utilizzo di state e setState diamo vita al lifecycle di React e dunque possiamo avere una visualizzazione degli elementi dinamica rispetto a quanto fa l’utente. Ovviamente setState può essere chiamato anche se riceviamo risposta da un endpoint che ci fornisce un json di dati e vogliamo mostrarli nel metodo render.
La cosa importante è non dimenticarsi che chiamare setState in un metodo come il render porta la vostra applicazione a vivere di un lifecycle infinito, ciò vuol dire vederla bloccare e dover riavviarla.
Se vuoi continuare a seguire questa guida ti ricordo di non perdere di vista l’articolo Come creare una web app da zero. Inoltre se ti iscrivi alla newsletter non ti perderai i nuovi articoli. Mando da 1 a 4 mail al mese ricapitolando dove siamo arrivati con ogni guida. Con la newsletter hai anche accesso a libri ed ebook gratuiti, così come a coupon Udemy ? .
Per dubbi o domande scrivimi 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!).