Se hai mai provato a gestire lo stato e gli effetti collaterali in React, sai quanto può diventare complesso. I hook useState useEffect sono la soluzione moderna e pulita che ha rivoluzionato lo sviluppo con i componenti funzionali, permettendoti di scrivere codice più leggibile e manutenibile senza ricorrere alle classi.
Il Problema: La Complessità delle Classi
Prima dell’introduzione degli Hooks in React 16.8, la gestione dello stato e del ciclo di vita di un componente era confinata ai Componenti Classe. Questo approccio, sebbene potente, portava spesso a codice verboso, difficile da seguire e con logica duplicata sparsa tra metodi come componentDidMount e componentDidUpdate.
Gli Hooks nascono proprio per risolvere questo problema, permettendo di “agganciare” le funzionalità di React, come lo stato, all’interno di componenti funzionali, più semplici e diretti.
Che cos’è useState? La Memoria del Componente
Immagina useState come la memoria a breve termine del tuo componente. È un hook che ti permette di dichiarare una “variabile di stato” e una funzione per aggiornarla. Ogni volta che questa variabile cambia, React ri-esegue il rendering del componente per mostrare il valore aggiornato.
La sua sintassi è concisa e si basa sulla destrutturazione di un array:
const [nomeDelloStato, funzionePerAggiornare] = useState(valoreIniziale);
Esempio Pratico: Un Semplice Contatore
Vediamo come implementare un contatore di click. Questo è l’esempio “Hello, World!” per useState.
import React, { useState } from 'react';
function Counter() {
// Dichiariamo una nuova variabile di stato chiamata "count"
// Il suo valore iniziale è 0
const [count, setCount] = useState(0);
return (
<div>
<p>Hai cliccato {count} volte</p>
{/* Quando il bottone viene cliccato, chiamiamo setCount per incrementare il valore */}
<button onClick={() => setCount(count + 1)}>
Clicca qui
</button>
</div>
);
}
In questo codice, useState(0) inizializza lo stato count a 0. La funzione setCount è l’unico modo per modificare count, garantendo che React sappia quando aggiornare l’interfaccia.

Che cos’è useEffect? L’Agente per gli Effetti Collaterali
Mentre useState gestisce lo stato *interno* del componente, useEffect si occupa di tutto ciò che interagisce con il mondo *esterno*. Queste interazioni sono chiamate “effetti collaterali” o “side effects”.
Alcuni esempi comuni di effetti collaterali includono:
- Chiamate a API esterne per recuperare dati.
- Iscrizione e pulizia di eventi (es.
window.addEventListener). - Manipolazione diretta del DOM (es. cambiare il titolo della pagina).
La sintassi base di useEffect accetta una funzione (l’effetto) e un array di dipendenze (opzionale).
useEffect(() => {
// Codice dell'effetto collaterale da eseguire
return () => {
// Funzione di pulizia (opzionale)
// Eseguita prima che il componente venga smontato o prima del prossimo effetto
};
}, [dipendenze]);
L’array di dipendenze è cruciale: dice a React *quando* rieseguire l’effetto. Se l’array è vuoto [], l’effetto viene eseguito solo una volta, al montaggio del componente. Se contiene delle variabili [count], l’effetto si riattiva ogni volta che una di quelle variabili cambia.
Come funzionano insieme i hook useState useEffect
La vera magia avviene quando combiniamo stato ed effetti. Creiamo un componente che recupera i dati di un utente da un’API fittizia e li mostra a schermo, gestendo anche lo stato di caricamento.
import React, { useState, useEffect } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
// Definiamo una funzione asincrona per il fetch
const fetchUserData = async () => {
setLoading(true); // Inizia il caricamento
try {
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);
const data = await response.json();
setUser(data); // Salviamo i dati nello stato
} catch (error) {
console.error("Errore nel fetch:", error);
} finally {
setLoading(false); // Finiamo il caricamento (sia in caso di successo che di errore)
}
};
fetchUserData();
}, [userId]); // L'effetto si riesegue solo se userId cambia
if (loading) {
return <p>Caricamento...</p>;
}
if (!user) {
return <p>Utente non trovato.</p>;
}
return (
<div>
<h2>{user.name}</h2>
<p>Email: {user.email}</p>
<p>Sito web: {user.website}</p>
</div>
);
}
In questo esempio, useEffect viene eseguito quando il componente viene montato (e ogni volta che userId cambia). Al suo interno, esegue una chiamata API e, una volta ricevuta la risposta, usa setUser e setLoading (le funzioni ottenute da useState) per aggiornare l’interfaccia.
Conclusione: La Coppia Perfetta
Capire a fondo il hook useState useEffect è il passo fondamentale per padroneggiare React moderno. useState fornisce la memoria, permettendo ai tuoi componenti di ricordare informazioni tra un rendering e l’altro. useEffect fornisce il ponte verso il mondo esterno, gestendo operazioni asincrone e interazioni con il browser.
Insieme, formano una coppia potente e flessibile che ti permette di costruire interfacce complesse con codice dichiarativo, pulito e facile da testare. Ora che hai compreso le basi, sei pronto per esplorare altri hook come useContext o useReducer.





