Guida ai React Hooks: useState

Impariamo ad usare useState per la gestione dello stato applicativo dei componenti funzionali di React.

Alessio Sferro
4 min readNov 15, 2020
Photo by Aleksandra Boguslawska on Unsplash

Come si gestisce lo stato applicativo in React? Ma andiamo per ordine, innanzitutto cosa intendiamo con stato applicativo?

Per semplificare la spiegazione, proviamo a fare un paragone con lo stato di uno studente universitario.

Ogni anno, lo studente dovrà preparare un certo numero di esami per essere ammesso all’anno accademico successivo. In questo caso, il suo stato applicativo potrebbe riguardare il numero degli esami superati nell’anno in corso e quello degli esami rimanenti alla laurea, oppure il numero dei suoi CFU.

Lo stato di un applicazione non è altro che il valore di certe variabili riguardanti il suo comportamento in un certo istante di tempo

Lo stato dello studente non rimarrà lo stesso e col passare del tempo supererà altri esami, quindi il conteggio degli esami rimanenti alla laurea e degli esami superati si aggiornerà, così come il numero dei suoi CFU.

Per farla breve, lo stato di un applicazione non è altro che il valore di certe variabili riguardanti il suo comportamento in un certo istante di tempo.

Tornando all’esempio dello studente, il numero dei suoi CFU sarà diverso se lo si prende all’inizio della sua carriera, in cui verrà considerato una matricola, o alla fine, in cui verrà considerato maturando ed infine laureato. Notiamo anche che il grado stesso dello studente potrebbe far parte dello stato, in quanto è una variabile soggetta al cambiamento col passare del tempo e che da informazioni sul comportamento dell’oggetto in questione (mi sembra chiaro che una matricola non possa prendere in giro altre matricole).

Chiarito il concetto di stato applicativo, passiamo alla sua gestione in React. Per gestire lo stato applicativo di un componente in React, potremmo pensare che sia sufficiente memorizzare una variabile e aggiornarla a seguito di un qualche evento, come nel seguente modo:

Implementazione non corretta di uno stato applicativo in React

In tal modo possiamo tuttavia notare che scrivendo nell’input di testo non solo questo rimane vuoto, ma la variabile message verrà aggiornata solamente con l’ultima lettera inserita, il che non è quello che vogliamo. Ma qual è il motivo di tutto ciò?

L’utilizzo dell’hook useState è indispensabile per il mantenimento di uno stato applicativo in sync con la view renderizzata da React

In pratica, React effettua un render del codice JSX restituito dal componente quando viene inizialmente montato dal motore di rendering interno. Una volta effettuato il rendering iniziale, i successivi rendering avverranno unicamente a seguito di aggiornamenti dello stato del componente.

Pertanto, l’utilizzo dell’hook useState è indispensabile per il mantenimento di uno stato applicativo in sync con la view renderizzata da React.

L’hook useState restituisce un array che contiene al primo slot il valore della porzione di stato aggiornata all’ultimo render, mentre al secondo una funzione che ne permette l’aggiornamento. Ogni volta che la funzione di aggiornamento viene invocata e le viene passato un nuovo valore, React effettuerà un rendering del componente aggiornando unicamente gli elementi del DOM che riflettono il valore della porzione di stato aggiornata.

Quest’ultimo punto è uno dei motivi della popolarità di React ed il perché della sua velocità.

Di seguito, l’esempio corretto della gestione dello stato tramite useState:

Implementazione corretta di uno stato applicativo in React

In questo modo, possiamo vedere che logica e view dell’applicazione sono sincronizzate e la variabile message viene aggiornata non più con l’ultima lettera, ma bensì con l’intera stringa inserita nel campo di input.

A questo punto, è semplice arrivare a capire perché la variabile message nell’esempio precedente non venga aggiornata con l’intera stringa: aggiornando il valore della variabile, dato che non utilizziamo l’hook useState, React non sa di dover effettuare un re-rendering della view e pertanto il suo valore torna ad essere quello di una stringa vuota. Insomma, un po’ come se lo studente dell’esempio precedente andasse in giro mentendo circa il superamento di un esame: chi lo ascolta potrebbe pure credergli, ma l’università sa perfettamente che ciò non corrisponde alla realtà!

Nel caso in cui si debba inizializzare una porzione di stato utilizzando logiche più complesse oppure con oggetti anziché primitive, è possibile passare ad useState una callback che verrà eseguita in maniera lazy solamente al primo render del componente. Inoltre, se l’aggiornamento dello stato dipende da uno stato precedente, si può passare una callback alla funzione di aggiornamento, in cui sarà possibile avere come parametro in ingresso lo stato precedente.

Rimane un’ultima considerazione da fare: per ottimizzare al meglio il codice, infatti, sarebbe meglio non dichiarare delle variabili o costanti come STRINGS o HANDLERS all’interno di un componente React. Come possiamo osservare in questo esempio, in cui aggiorniamo il valore della variabile test all’interno di updateCountHandler , anche se la view viene aggiornata per via dell’invocazione della funzione setCount che provvede ad aggiornare la porzione di stato count del componente, al prossimo render la variabile test avrà comunque il suo valore iniziale, ovvero “init”.

Qual è il motivo? Ogni volta che viene effettuato il rendering del componente, le variabili interne al componente vengono ridefinite e riassegnate da capo. In certi casi, spostare variabili e costanti all’esterno di un componente non è possibile perché potrebbero essere derivate dalle props. In questo caso, potrebbe essere necessario l’utilizzo di altri hooks, come useMemo ed useCallback , di cui parleremo in seguito. Per il momento, possiamo effettuare un refactoring del codice già visto come segue:

Implementazione corretta ed ottimizzata di uno stato applicativo in React

Abbiamo capito cos’è lo stato applicativo, perché bisogna utilizzare l’hook useState, come funziona il rendering dei componenti di React e uno dei motivi più importanti della popolarità di React.

Ci vediamo al prossimo episodio della serie, con l’hook useEffect!
Stay tuned.

Photo by Willian Justen de Vasconcellos on Unsplash

--

--

Alessio Sferro

Appassionato da sempre di tecnologia, algoritmi e sviluppo software, adoro creare applicazioni altamente dinamiche e reattive e risolvere problemi impegnativi.