React è una popolare libreria JavaScript utilizzata per la creazione di interfacce utente. Offre a sviluppatrici e sviluppatori un’ampia gamma di strumenti, tra cui gli hook, che permettono di creare applicazioni in modo più semplice ed efficiente.
Uno degli hook più utilizzati è useState
, che permette di aggiungere uno stato ai componenti funzionali.
In questo articolo offriremo un’analisi approfondita di useState
, analizzandone impieghi e best practice.
Cos’è l’hook useState?
Prima di addentrarci nelle specifiche di useState
, definiamo innanzitutto gli hook e quali sono le differenze rispetto ai tradizionali componenti di classe.
Un hook è una funzione che permette di utilizzare lo stato e altre caratteristiche di React in componenti funzionali.
A differenza dei componenti di classe, i componenti funzionali non possono memorizzare lo stato. Gli hook come useState
risolvono questo problema permettendo di aggiungere lo stato ai componenti funzionali.
Il backgroung dell’hook useState
Prima dell’introduzione dell’hook useState
in React 16.8, i componenti funzionali non erano in grado di conservare il proprio stato. Gli sviluppatori dovevano invece utilizzare componenti di classe o librerie esterne di gestione dello stato come Redux per gestire lo stato nelle applicazioni.
Sebbene i componenti di classe e le librerie esterne di gestione dello stato siano ancora soluzioni valide, l’introduzione dell’hook useState
ha reso molto più semplice aggiungere lo stato ai componenti funzionali e ha semplificato l’API di React nel suo complesso.
Con l’hook useState
gli sviluppatori possono utilizzare i componenti funzionali nella maggior parte delle applicazioni, riducendo la quantità di codice boilerplate necessario e rendendo più semplice la valutazione dello stato.
Elementi della sintassi useState
L’hook useState
prende come argomento un valore di stato iniziale e restituisce un array contenente due elementi: il valore di stato corrente e una funzione che aggiorna il valore di stato.
Ecco la sintassi:
const [state, setState] = useState(initialState);
state
: il valore corrente dello stato.setState
: una funzione che aggiorna il valore dello stato.initialState
: il valore iniziale della variabile di stato che si sta dichiarando. È facoltativo. Se non viene fornito alcun valore (non è consigliabile), questo viene automaticamente impostato suundefined
.
È importante notare che, quando si utilizza l’hook useState
, ogni volta che il valore dello stato cambia, React eseguirà automaticamente un nuovo rendering del componente.
Come utilizzare l’hook useState
Per utilizzare useState
, bisogna invocare la funzione e passarle un valore iniziale come argomento. La funzione restituisce un array contenente il valore dello stato corrente e una funzione per aggiornare lo stato.
Ecco un esempio per la gestione di un semplice contatore:
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
export default Counter;
In questo esempio, inizializziamo lo stato di count
a 0 utilizzando useState
. Poi renderizziamo il valore del conteggio corrente e un pulsante. Quando il pulsante viene cliccato, il valore del conteggio sarà incrementato perché abbiamo aggiunto una funzione freccia con la funzione setCount
.
<button onClick={() => setCount(count + 1)}>Click me</button>
Quando si usa l’hook useState
, è importante ricordare di importarlo dalla libreria React. Se ci si dimentica di importarlo, è probabile che si verifichino degli errori. Ecco come importare useState:
import { useState } from 'react';
Includendo useState
nella dichiarazione di importazione, stiamo dicendo a React che vogliamo utilizzare l’hook useState
nel nostro componente.
Utilizzare diversi tipi di dati in React con useState
L’hook useState
di React non si limita a gestire solo i tipi di dati stringa o numerici. È possibile utilizzarlo per gestire gli stati di diversi tipi di dati, come array, oggetti e booleani.
Utilizzare gli array con l’hook useState
È possibile utilizzare l’hook useState
per gestire un array in React. Ad esempio, se abbiamo un array di frutti, possiamo inizializzare lo stato con l’array:
import { useState } from 'react';
function App() {
const [list, setList] = useState(['apple', 'banana', 'orange']);
const addToList = () => {
const newItem = 'grape';
setList([...list, newItem]);
};
return (
<div>
<ul>
{list.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
<button onClick={addToList}>Add Item</button>
</div>
);
}
export default App;
In questo esempio, utilizziamo useState
per gestire un array chiamato list
. Lo stato iniziale di list
è impostato su un array contenente tre elementi: apple, banana e orange.
Abbiamo anche creato una funzione addToList
che copia tutti gli elementi dell’array con l’operatore spread (...
) e poi aggiunge un nuovo elemento grape all’array list
ogni volta che viene cliccato il pulsante “Aggiungi elemento”.
Questa volta non aggiorneremo lo stato in linea utilizzando una funzione freccia perché è più opportuno creare questa operazione come funzione indipendente e invocarla attraverso il metodo onClick
aggiunto al pulsante Aggiungi elemento.
Utilizzare gli oggetti con useState
Possiamo utilizzare l’hook useState
anche per gestire un oggetto in React. Ecco un esempio:
import { useState } from 'react';
function App() {
const [user, setUser] = useState({ name: 'John', age: 30 });
const handleClick = () => {
setUser({ ...user, age: user.age + 1 });
};
return (
<div>
<p>Name: {user.name}</p>
<p>Age: {user.age}</p>
<button onClick={handleClick}>Increase Age</button>
</div>
);
}
export default App;
In questo esempio, utilizziamo useState
per gestire un oggetto chiamato user. Lo stato iniziale di user
è impostato su un oggetto contenente due proprietà: name e age.
Abbiamo anche una funzione handleClick
che copia tutti i dati dell’oggetto con l’operatore di diffusione (...
) e aumenta l’età dell’utente di 1 ogni volta che viene cliccato il pulsante Increase Age.
È importante sapere che è possibile assegnare questo oggetto a una variabile e poi inizializzare la variabile. Questo è utile quando si ha un oggetto o un array di grandi dimensioni e si vuole scrivere un codice di facile comprensione:
import { useState } from 'react';
// Declare data
let userData = {
name: 'John',
age: 30,
};
function App() {
const [user, setUser] = useState(userData);
const handleClick = () => {
setUser({ ...user, age: user.age + 1 });
};
return (
<div>
<p>Name: {user.name}</p>
<p>Age: {user.age}</p>
<button onClick={handleClick}>Increase Age</button>
</div>
);
}
export default App;
Utilizzare i booleani con useState
Si può anche utilizzare l’hook useState
per gestire un valore booleano. Ecco un esempio:
import { useState } from 'react';
function App() {
const [isOn, setIsOn] = useState(false);
const toggleSwitch = () => {
setIsOn(!isOn);
};
return (
<div>
<p>The switch is {isOn ? 'on' : 'off'}</p>
<button onClick={toggleSwitch}>Toggle Switch</button>
</div>
);
}
export default App;
In questo esempio, utilizziamo useState
per gestire un valore booleano chiamato isOn
. Lo stato iniziale di isOn
è impostato su false
. Abbiamo anche una funzione toggleSwitch
che altera il valore di isOn
ogni volta che viene cliccato il pulsante Toggle Switch.
Questa funzione può essere utilizzata per gestire l’alternanza delle modalità scura e chiara nei progetti.
Prima di concludere, analizziamo un utilizzo più avanzato dell’hook useState
con i moduli.
L’hook useState e i moduli
Per gestire i dati dei moduli e gli input degli utenti in React, si utilizza lo stato. Questo viene utilizzato per tenere traccia dei valori correnti degli elementi del modulo. Tiene traccia di tutte le interazioni dell’utente, come la digitazione di un input di testo o la selezione di un’opzione da un menu a tendina, e infine aggiorna lo stato con il nuovo valore.
Ecco un esempio di utilizzo di useState
per la creazione di un semplice modulo:
import { useState } from 'react';
let formStateData = {
firstName: '',
lastName: '',
email: '',
};
function Form() {
const [formData, setFormData] = useState(formStateData);
const handleInputChange = (event) => {
const { name, value } = event.target;
setFormData({ ...formData, [name]: value });
};
const handleSubmit = (event) => {
event.preventDefault();
console.log(formData);
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
name="firstName"
value={formData.firstName}
onChange={handleInputChange}
/>
<input
type="text"
name="lastName"
value={formData.lastName}
onChange={handleInputChange}
/>
<input
type="email"
name="email"
value={formData.email}
onChange={handleInputChange}
/>
<button type="submit">Submit</button>
</form>
);
}
export default Form;
In questo esempio, creiamo innanzitutto un oggetto per i dati che verranno raccolti con il modulo, con valori predefiniti per i campi firstName, lastName e email. Poi inizializziamo lo stato formData
utilizzando useState
.
let formStateData = {
firstName: '',
lastName: '',
email: '',
};
const [formData, setFormData] = useState(formStateData);
Definiamo poi una funzione handleInputChange
che aggiorna lo stato formData
ogni volta che un campo del modulo viene modificato.
const handleInputChange = (event) => {
const { name, value } = event.target;
setFormData({ ...formData, [name]: value });
};
Infine, definiamo una funzione handleSubmit
che registra i dati correnti del modulo nella console quando il modulo viene inviato.
const handleSubmit = (event) => {
event.preventDefault();
console.log(formData);
};
Best practice di useState
Quando si utilizza l’hook useState
, è importante seguire le best practice per evitare errori e garantire prestazioni ottimali. Ecco alcuni suggerimenti:
- Evitare stati annidati profondamente: invece di memorizzare dati di stato complessi in un unico oggetto, è bene valutare la possibilità di suddividerli in parti più piccole per semplificarne la gestione.
- Utilizzare aggiornamenti funzionali: quando si aggiorna lo stato in base allo stato precedente, è bene utilizzare gli aggiornamenti funzionali per evitare race condition e garantire che venga aggiornato lo stato corretto.
- Evitare aggiornamenti eccessivi dello stato: l’aggiornamento dello stato può essere dispendioso, quindi è bene cercare di ridurre al minimo il numero di aggiornamenti. Si può prendere in considerazione l’hook
useEffect
per raggruppare gli aggiornamenti e ottimizzare le prestazioni. - Evitare i re-rendering non necessari: React esegue un nuovo rendering di un componente ogni volta che lo stato o le proprietà cambiano. Per evitare i re-rendering non necessari, si può utilizzare la funzione memo.
Riepilogo
In questo articolo abbiamo analizzato l’hook useState
e abbiamo visto come utilizzarlo per aggiungere lo stato ai componenti funzionali. Abbiamo anche visto come utilizzare useState
con moduli, array e oggetti e suggerito alcune best practice per ottenere prestazioni ottimali. Seguendole, potrete creare applicazioni React efficienti, scalabili e facili da mantenere.
State cercando la soluzione di hosting ideale per le vostre applicazioni React? Provate gratuitamente l’Hosting di Applicazioni di Kinsta!