React Intermedio: Gestire lo Stato con useState e il Ciclo di Vita (Parte 2/2)

Dopo aver compreso JSX, Componenti e Props, è tempo di rendere le tue applicazioni interattive. Questa seconda parte della guida completa ti insegna a gestire lo **Stato (State)** con l’Hook useState e a reagire agli eventi dell’utente. Essenziale per ogni sviluppatore React moderno.

Nella prima parte di questa guida, abbiamo stabilito le fondamenta: la sintassi JSX, il concetto di Componente Funzionale e il flusso di dati unidirezionale tramite le Props. Tuttavia, le Props rappresentano solo dati statici o dati che arrivano dal genitore. E se un componente avesse bisogno di tracciare le modifiche interne, come il conteggio dei “Mi Piace” o il valore di un campo di input?

La risposta è lo **Stato (State)**. Lo Stato è il cuore pulsante della dinamicità in React: è un oggetto di memoria interna che, quando viene modificato, costringe React a **re-renderizzare** il componente e a ricalcolare il Virtual DOM.

1. L’Hook useState: La Chiave per lo Stato Moderno

Prima dell’introduzione degli Hooks (React 16.8), la gestione dello stato era appannaggio esclusivo dei Componenti basati su Classi. Oggi, l’Hook useState è il metodo standard per dotare i Componenti Funzionali di memoria interna.

Sintassi e Flusso di Lavoro

useState è una funzione che, quando richiamata, restituisce un array con esattamente due elementi. È prassi comune usare la **destrutturazione degli array** per accedere a questi due valori:


    import React, { useState } from 'react';

    const [valore, setValore] = useState(valoreIniziale);
    

Cosa significano i due elementi restituiti?

  1. **`valore`**: La variabile di stato corrente (il valore che stai leggendo).
  2. **`setValore`**: La funzione che devi usare per aggiornare quel valore. **Mai** modificare `valore` direttamente!

Il `valoreIniziale` è l’unico argomento che passi a useState ed è utilizzato solo al primo render del componente.

Esempio Pratico: Un Contatore

Vediamo l’applicazione più semplice, un contatore, che illustra perfettamente come lo Stato attiva il re-render:


    const Contatore = () => {
      // Stato iniziale: 0
      const [conteggio, setConteggio] = useState(0);

      const incrementa = () => {
        // Usa SEMPRE la funzione setter per cambiare lo stato
        setConteggio(conteggio + 1); 
      };

      return (
        <div>
          <p>Il conteggio attuale è: {conteggio}</p>
          <button onClick={incrementa}>Aumenta</button>
        </div>
      );
    };
    

Quando l’utente clicca sul pulsante, viene eseguita `incrementa()`, che chiama `setConteggio()`. React riconosce il cambiamento e riesegue l’intera funzione `Contatore()`, aggiornando il valore visualizzato a schermo.

2. Gestire gli Eventi: Il Ponte tra Utente e Stato

Gestire gli eventi (click, submit, change) in React è molto simile a come faresti con l’HTML puro, ma con alcune differenze chiave che mantengono la coerenza con JSX.

Differenze Chiave con HTML

  • **CamelCase:** I nomi degli eventi sono scritti in *camelCase* (e.g., `onClick`, non `onclick`).
  • **Passaggio di Funzioni:** Non passi una stringa di codice JavaScript come faresti in HTML (e.g., `onclick=”doSomething()”`). Invece, passi una **funzione JavaScript** all’attributo, racchiusa tra graffe (e.g., `onClick={doSomething}`).
  • **Oggetto Evento Sintetico:** React passa un `SyntheticEvent` che standardizza il comportamento degli eventi su tutti i browser.

**Esempio:** Se devi passare parametri all’handler (alla funzione che gestisce l’evento), devi avvolgere la chiamata in una funzione anonima (una *arrow function*):


    // Se la funzione ha bisogno di argomenti, usa una funzione anonima
    <button onClick={() => handleAction('delete')}>Elimina</button>
    

3. Errori Comuni da Evitare (Best Practice)

Quando si inizia con lo Stato, gli sviluppatori junior commettono spesso questi errori, che portano a bug insidiosi:

  • **Mai modificare lo Stato direttamente:** Scrivere `conteggio = 5;` non attiverà il re-render. Devi **sempre** usare la funzione setter (`setConteggio(5)`).
  • **Aggiornamento Asincrono:** Le chiamate a `setState` o `setValore` sono asincrone. Se il nuovo stato dipende dal valore precedente (come nel nostro contatore), dovresti passare una funzione di callback al setter per garantire che si basi sullo stato più aggiornato.

    // Modalità Sicura per gli aggiornamenti basati sullo stato precedente
    const incrementaSicuro = () => {
      setConteggio(prevConteggio => prevConteggio + 1); 
    };
    

Utilizzando la forma `setValore(funzione)`, si riceve in input lo stato precedente (`prevConteggio`), eliminando il rischio di *race condition* (condizione di gara) dovute all’asincronia.

4. Side Effects: Cosa Succede Dopo il Render?

A volte, dopo che il componente è stato renderizzato (o ri-renderizzato a causa di un cambio di stato), è necessario eseguire un’azione secondaria. Queste sono chiamate **Side Effects** (effetti collaterali): recuperare dati da API, aggiornare il titolo della pagina, impostare timer, ecc.

In React, gli Side Effects sono gestiti con l’Hook **useEffect**.

Se `useState` gestisce “la memoria” del componente, `useEffect` gestisce “la vita” del componente (il montaggio, l’aggiornamento e lo smontaggio).

Per ora, ricorda che ogni volta che devi “parlare” con il mondo esterno (API, browser DOM), devi usare useEffect. Approfondiremo l’uso di `useEffect` (con le sue *dependency array*) in una guida più avanzata.

Conclusione: Hai Sbloccato la Dinamicità

Complimenti! Con la comprensione di Componenti, Props e **Stato**, hai sbloccato la capacità di scrivere applicazioni davvero interattive. Non stai più solo disegnando l’interfaccia; stai gestendo il flusso di dati che la anima.

Continua a fare pratica con useState e a gestisce diversi tipi di dati (oggetti, array) per cementare queste basi fondamentali. Il prossimo passo naturale è imparare come suddividere la logica complessa con `useEffect` e `useReducer`.

📌 **Risorsa Aggiuntiva:** Salva e riapri questa guida ogni volta che devi implementare un contatore, un toggle o un campo form in React. Esercitati a usare sempre la forma funzionale del setter (`setValore(prev => …)`) per gli aggiornamenti più sicuri.