React Real World Vademecum
Parte I: Il Paradigma React
Prima di scrivere un singolo componente, devi capire perché React esiste e cosa ha cambiato per sempre. Questa prima parte non è un'introduzione opzionale: è la differenza tra usare React meccanicamente e capirlo davvero.
Il Paradigma React
1. Perché "React"? (Il Nome Ha una Storia)
React non si chiama così per caso. Il nome rivela tutto l'intento della libreria: creare interfacce utente che reagiscono automaticamente ai dati. Per capire la rivoluzione, devi prima capire il problema che doveva risolvere.
L'Idea Centrale: Una UI che Reagisce ai Dati
Pensa a come funziona un termostato moderno. Non devi alzarti e regolare il riscaldamento ogni volta che la temperatura cambia: tu imposti la temperatura desiderata, e il termostato reagisce automaticamente allo stato corrente della stanza per raggiungerla.
Questo è esattamente il principio di React: tu dichiari lo stato desiderato della tua UI, e React si occupa da solo di aggiornare il browser per rispecchiarlo.
Prima di React, la vita di un programmatore front-end era diversa.
// IL VECCHIO MODO (JavaScript Vanilla)
// Ogni volta che i dati cambiano, devi ricordarti di aggiornare OGNI parte del DOM
function aggiornaUI(nuoviDati) {
// Ricordati del titolo...
document.querySelector('#titolo').textContent = nuoviDati.nome;
// ...del contatore...
document.querySelector('#contatore').textContent = nuoviDati.notifiche;
// ...del badge...
document.querySelector('.badge').classList.toggle('nascosto', nuoviDati.notifiche === 0);
// ...e così via per ogni elemento che dipende dai dati
}
Con React, scrivi una sola volta come la UI deve apparire per ogni possibile stato dei dati. Poi aggiorni i dati, e React pensa al resto.
Il Problema di Facebook nel 2013
La storia di React nasce da un problema concreto che Facebook aveva con la sua interfaccia. Immagina la barra delle notifiche in alto: mostrava un numero. Poi la chat a sinistra: mostrava messaggi non letti. Poi i commenti nei post: mostravano nuove risposte. Tutti questi elementi dovevano rimanere sincronizzati con gli stessi dati.
Con JavaScript Vanilla, ogni piccola modifica richiedeva di aggiornare manualmente decine di elementi nel DOM. Se dimenticavi uno, avevi un bug. Se la struttura cambiava, dovevi riscrivere tutto. Il codice diventava impossibile da mantenere.
Jordan Walke, un ingegnere di Facebook, creò React nel 2011 (rilasciato pubblicamente nel 2013) per risolvere esattamente questo: rendere la UI automaticamente sincronizzata con i dati, senza intervento manuale.
Il "Reactive" nel nome
React prende ispirazione dal concetto di programmazione reattiva, ma non ne è un'implementazione pura in senso accademico. È una semplificazione pratica dell'idea: invece di scrivere "quando cambia X, aggiorna Y e Z", scrivi "la UI è questa quando X ha questo valore". React si occupa di capire cosa deve cambiare e quando.
2. Libreria vs Framework (Il Modello IKEA)
Sentirai spesso la domanda: "React è una libreria o un framework?". La risposta corretta è: è una libreria. Ma capirne il perché è più utile della risposta in sé.
Cos'è una Libreria? (IKEA)
Una libreria è una collezione di strumenti che tu chiami quando ne hai bisogno. Tu sei in controllo. Decidi quando usarla, come integrarla, e cosa fare con il resto dell'applicazione.
Pensa a IKEA. Entri, scegli i mobili che ti servono, paghi, esci. Poi assembli tutto a casa tua come vuoi tu. Decidi dove mettere il divano, se mettere un tappeto, come organizzare la cucina. IKEA ti vende i pezzi, non ti impone come arredare casa.
React è IKEA: ti dà gli strumenti per costruire la tua interfaccia, ma non ti dice come strutturare il routing, come gestire lo stato globale, come comunicare con il server. Quelle sono tue decisioni.
Caratteristica Chiave: Sei Tu a Chiamare la Libreria
Quando usi React, è il tuo codice che importa e chiama i componenti di React. La libreria non sa niente del resto della tua applicazione finché non la invochi tu.
Cos'è un Framework? (Il Condominio di Lusso)
Un framework è l'opposto: è lui che chiama te. Questo concetto ha un nome preciso: Inversion of Control (Inversione del Controllo).
Immagina un condominio di lusso. Le pareti portanti sono già messe. La cucina è già nel posto prestabilito. I cavi dell'elettricità passano in percorsi fissi. Puoi scegliere il colore delle pareti, ma non puoi spostare la cucina nel bagno. Il condominio ha già preso le decisioni strutturali per te.
Un framework funziona così: ti dice dove mettere i file, come chiamarli, come strutturarli. Quando l'app si avvia, è il framework che chiama il tuo codice, non viceversa.
Esempi di veri framework:
- Angular: ha tutto incorporato (routing, form, HTTP client, testing). Entri in casa già arredata.
- Docusaurus: vuoi un sito di documentazione? I tuoi file
.mdo.mdxvanno in/docs/, i blog post in/blog/. Non puoi farla diversamente.
Il vantaggio dei framework è che hai meno decisioni da prendere essendo le convezioni standardizzate, il grosso svantaggio è che ha molta meno libertà, è infatti più difficile da personalizzare.
React nel Mondo Reale: La Libreria che Diventa un Framework
Ecco la verità pratica che è importante conoscere fin da subito:
React da solo è solo una libreria per la UI. Non ha un router incorporato, né un sistema di autenticazione, così come un modo standard di fare fetch dei dati.
Ma non si usa mai React da solo in produzione. Appena aggiungi:
- React Router (per la navigazione)
- useState + Context (per lo stato globale)
- Vite (per il build)
- React Query (per il data fetching)
...hai costruito il tuo framework artigianale. Hai preso tutte le decisioni IKEA tu stesso.
Next.js è la risposta all'inevitabilità di questo processo: è un framework basato su React che ha già preso quelle decisioni per te. Ha routing incorporato, SSR incorporato, data fetching incorporato. È il condominio di lusso costruito sui mattoni IKEA di React.
React (libreria) → gestisce solo la UI
React + Router + State → il tuo framework artigianale
Next.js → framework pronto, decisioni già prese
Regola pratica:
Per progetti piccoli e per imparare → React con Vite (sei tu il capo). Per progetti di produzione complessi → considera Next.js (qualcuno ha già scelto per te).
3. SPA, MPA, SSR, SSG, RSC (React Non È Sempre una SPA)
Uno degli equivoci più comuni tra chi inizia con React: "React = app a pagina singola". Non è sempre vero. React è uno strumento che può essere usato in molti modi diversi. Capire le differenze ti permette di scegliere l'architettura giusta per ogni progetto.
Il Web Classico (MPA, Multi-Page Application)
Prima delle SPA, tutto il web funzionava così. Ogni click su un link o ogni submit di un form scatenava una sequenza:
- Il browser inviava una richiesta al server
- Il server costruiva una pagina HTML completa
- Il browser riceveva l'HTML e demoliva l'intera pagina corrente
- Il browser ridisegnava tutto da zero con la nuova pagina
Analogia: Un teatro dove tra una scena e l'altra viene demolito il palco, ricostruito, ridipinto e riallestito da zero, mentre il pubblico aspetta al buio.
Il "trauma del browser" è quello schermo bianco di qualche secondo tra una pagina e l'altra. Funzionava, ma la UX era discontinua.
L'Illusione della SPA (Single-Page Application)
React ha reso popolare un approccio diverso: l'intera app vive in un unico file index.html. React intercetta i click sui link, capisce quale "pagina" mostrare e sostituisce solo la parte del DOM che deve cambiare, senza mai ricaricare il browser.
Analogia: Lo stesso teatro, ma il palco rimane fermo. Il pubblico non si alza mai. Mentre lo spettacolo continua, alcuni operai silenziosi cambiano solo le scenografie necessarie.
Nessuna pagina bianca. Transizioni istantanee. UX fluida come un'app nativa.
// Con React Router, la "navigazione" è un'illusione controllata
// Non si scarica una nuova pagina, React scambia i componenti
<Routes>
<Route path="/" element={<HomePagina />} />
<Route path="/profilo" element={<Profilo />} />
<Route path="/negozio" element={<Negozio />} />
</Routes>
I Problemi della SPA Pura
Sviluppare una Single Page Application comporta due compromessi principali:
- Pessima SEO (Indicizzazione): Al primo contatto, Google riceve un file HTML completamente vuoto. I contenuti veri vengono "iniettati" da JavaScript solo in un secondo momento. Poiché i bot dei motori di ricerca vanno di fretta, spesso non aspettano questa elaborazione, non leggono i contenuti e non indicizzano il sito.
- Caricamento iniziale (Initial Load) lento: Un utente con connessione debole fisserà una schermata bianca a lungo. Prima di potergli mostrare anche solo un bottone, il browser è costretto a scaricare, decodificare e avviare l'intero "pacchetto" JavaScript che fa funzionare l'applicazione.
SSR (Server-Side Rendering)
I due problemi della SPA (SEO e caricamento iniziale lento) hanno riportato in auge un vecchio approccio, riadattato in chiave moderna.
In una SPA classica il rendering è client-side (CSR): il server invia al browser un file HTML quasi vuoto insieme a un grosso pacchetto JavaScript, e il browser deve eseguire tutto quel codice prima di poter mostrare qualcosa. È come comprare un mobile all'IKEA: ti arriva smontato e devi assemblarlo tu a casa.
Con il Server-Side Rendering (SSR) il lavoro si sposta sul server. Quando un utente richiede una pagina, il server esegue React, costruisce l'HTML completo con tutti i contenuti già inseriti e lo invia al browser pronto da visualizzare. È come andare al ristorante: il piatto arriva già preparato al tavolo e puoi mangiare subito.
Il vantaggio è doppio: l'utente vede la pagina istantaneamente (nessuna attesa del JavaScript) e i motori di ricerca trovano un HTML pieno di contenuti da indicizzare.
Hydration, il Risveglio di React
L'HTML che arriva dal server è statico, come una fotografia: si vede tutto ma non si può cliccare nulla. A quel punto React si carica nel browser e "si aggancia" a quell'HTML già presente, collegando gli eventi e gli hook per rendere la pagina interattiva senza doverla ridisegnare da zero. Questo processo si chiama Hydration.
I framework SSR più usati con React sono Next.js (il più popolare) e Remix.
SSG (Static Site Generation)
Con l'SSG, React non gira nel browser dell'utente. Viene usato solo durante la fase di compilazione (la build), prima ancora che il sito vada online. In quel momento il framework esegue tutti i componenti React, genera le pagine HTML corrispondenti e le salva come file statici. Quando un visitatore apre il sito, il suo browser scarica HTML già pronto, senza dover eseguire JavaScript pesante e senza bisogno di un server attivo.
È come scrivere un libro con un software di impaginazione professionale: lo strumento è sofisticato, ma il prodotto finale è un PDF che chiunque può aprire senza avere quel software installato.
Strumenti SSG principali: Gatsby, Astro, Next.js (con getStaticProps). Ideale per blog, documentazione e siti marketing, ovvero contenuti che cambiano raramente.
RSC (React Server Components), la Nuova Frontiera
Con SSR e SSG, il server genera l'HTML ma poi spedisce comunque al browser tutto il JavaScript necessario per far funzionare React. I React Server Components fanno un passo ulteriore: certi componenti vengono eseguiti esclusivamente sul server e al browser arriva solo il loro risultato HTML, senza che una singola riga del loro codice JavaScript venga mai scaricata dall'utente.
// Questo componente vive solo sul server
// Il browser non riceverà mai questo codice, solo il suo output HTML
async function ListaArticoli() {
const articoli = await leggiDalDatabase(); // accesso diretto al database, no API
return (
<ul>
{articoli.map(a => <li key={a.id}>{a.titolo}</li>)}
</ul>
);
}
Il vantaggio principale è la riduzione del bundle size: le librerie che un componente server importa (ad esempio un parser Markdown da 50 KB) restano sul server e non finiscono mai nel pacchetto che l'utente scarica.
Riepilogo Pratico: React È Agnostico
SPA pura React + React Router (navigazione client-side)
SSR Next.js o Remix (server genera l'HTML)
SSG Next.js / Gatsby / Astro (build genera HTML statici)
Ibrida React iniettato in una pagina HTML esistente
Regola: React non è "sempre una SPA". L'architettura dipende dal progetto.
4. Virtual DOM e Riconciliazione (Il Progetto dell'Architetto)
Con JavaScript Vanilla manipoli il DOM direttamente: selezioni un elemento, ne cambi il testo, ne aggiungi un altro. React invece non tocca mai il DOM direttamente. Per capire perché ha scelto questa strada, bisogna capire quanto costa al browser ogni singola modifica del DOM.
Perché Non Toccare il DOM Direttamente?
Ogni nodo del DOM (ogni <div>, ogni <p>, ogni <button>) è un oggetto JavaScript con centinaia di proprietà ereditate dalla gerarchia di prototype del browser. Modificare anche solo uno di questi oggetti innesca una sequenza costosa:
- Reflow (Layout): il browser ricalcola le dimensioni e le posizioni di tutti gli elementi che potrebbero essere stati influenzati dalla modifica
- Repaint: ridisegna i pixel sullo schermo nella zona interessata
Se fai quattro modifiche consecutive, il browser potrebbe dover ricalcolare il layout quattro volte. È come spostare un muro in un cantiere: non basta abbattere il muro, devi anche ricalcolare dove passano i tubi e i cavi elettrici che lo attraversavano.
// POTENZIALMENTE LENTO, ogni riga tocca il DOM reale
elemento1.textContent = nuoviDati.titolo; // Reflow + Repaint
elemento2.style.display = 'block'; // Reflow + Repaint
elemento3.classList.add('attivo'); // Reflow + Repaint
elemento4.setAttribute('disabled', true); // Reflow + Repaint
In app complesse con decine di aggiornamenti al secondo, questo processo può rendere l'esperienza lenta e scattosa.
Il Virtual DOM (Il Progetto su Carta)
React risolve questo problema interponendo un livello intermedio tra il tuo codice e il DOM reale: il Virtual DOM. È una rappresentazione leggera in JavaScript dell'albero del DOM, un semplice oggetto che descrive come dovrebbe apparire la UI in un dato momento.
// Versione semplificata di come React rappresenta internamente
// il tag <button className="rosso">Ciao</button>
{
tipo: 'button',
props: { className: 'rosso', children: 'Ciao' },
figli: []
}
Creare o modificare questo oggetto è velocissimo perché avviene interamente in memoria RAM, senza toccare nessun pixel sullo schermo. L'idea è la stessa di un architetto che non sposta i muri nel cantiere reale ogni volta che vuole provare una disposizione diversa: li sposta prima sul progetto CAD, dove le modifiche sono istantanee e gratuite, e solo quando il progetto è definitivo manda gli operai a intervenire sul cantiere.
Diffing (Trova le Differenze)
Ogni volta che lo stato della tua app cambia, React esegue quattro passaggi:
- Chiama di nuovo il tuo componente (che è una funzione)
- La funzione restituisce un nuovo Virtual DOM (il progetto aggiornato)
- React lo confronta con il vecchio Virtual DOM (il progetto precedente)
- Identifica esattamente cosa è cambiato. Questo confronto si chiama Diffing
Il meccanismo è lo stesso del gioco "trova le differenze" tra due immagini quasi identiche: React le analizza in millisecondi e individua che, ad esempio, l'unica cosa cambiata è il testo dentro un pulsante.
Vecchio Virtual DOM: <button>0 like</button>
Nuovo Virtual DOM: <button>1 like</button>
↑
Differenza trovata: solo il testo!
Il Risultato: Precisione Chirurgica
Una volta completato il Diffing, React ha in mano la lista esatta delle differenze e va a toccare nel DOM reale solo i nodi che sono effettivamente cambiati. Tutto il resto della pagina rimane intatto, senza reflow né repaint inutili. Invece di demolire un intero appartamento per cambiare la maniglia di una porta, React manda un operaio a sostituire solo la maniglia.
DOM Reale prima: <button>0 like</button>
↑
React tocca SOLO il testo "0 like"
e lo sostituisce con "1 like"
DOM Reale dopo: <button>1 like</button>
Da sviluppatore, non interagisci mai direttamente con il Virtual DOM. Il tuo lavoro è scrivere JSX che descriva la UI desiderata, e React si occupa di tutto il processo di confronto e aggiornamento efficiente del DOM reale.
5. Dichiarativo vs. Imperativo (Il Passeggero del Taxi)
Questo è il cambiamento mentale più importante quando passi da JavaScript Vanilla a React. Non riguarda solo la sintassi: cambia il modo in cui ragioni sul codice.
Il Modo Imperativo (L'Istruttore di Guida)
Con JavaScript Vanilla, scrivi il codice in modo imperativo: descrivi ogni singolo passo da eseguire, nell'ordine preciso. È come un istruttore di guida che ti detta ogni gesto, dall'ordine in cui controllare gli specchietti fino al momento esatto in cui premere un pedale.
// MODO IMPERATIVO (JavaScript Vanilla)
// Devi descrivere COME fare ogni cosa
function mostraMessaggio(testo) {
// Step 1: trova l'elemento
const contenitore = document.querySelector('#messaggi');
// Step 2: crea il nuovo elemento
const nuovoDiv = document.createElement('div');
// Step 3: aggiungi la classe
nuovoDiv.classList.add('messaggio');
// Step 4: inserisci il testo
nuovoDiv.textContent = testo;
// Step 5: aggiungi al DOM
contenitore.appendChild(nuovoDiv);
// Step 6: se ci sono troppi messaggi, rimuovi il più vecchio
if (contenitore.children.length > 5) {
contenitore.removeChild(contenitore.firstChild);
}
}
Se dimentichi un passaggio l'app si rompe, e se la struttura HTML cambia devi riscrivere tutto il codice che la manipola.
Il Modo Dichiarativo (Il Passeggero del Taxi)
Con React il ragionamento si ribalta. Scrivi il codice in modo dichiarativo: descrivi lo stato finale desiderato e React capisce da solo come arrivarci. È come salire su un taxi e dire "Piazza del Duomo, grazie" senza specificare quale strada prendere. Dai la destinazione, non le istruzioni.
// MODO DICHIARATIVO (React)
// Descrivi COSA vuoi vedere per ogni stato possibile
function ListaMessaggi({ messaggi }) {
return (
<div id="messaggi">
{messaggi.slice(-5).map(msg => (
<div key={msg.id} className="messaggio">
{msg.testo}
</div>
))}
</div>
);
}
Noti la differenza? Non dici a React "crea un div, aggiungi la classe, rimuovi il vecchio". Dici "Questa è la UI che voglio vedere quando messaggi contiene questi dati", e React si occupa di confrontare la UI attuale con quella desiderata, capire le differenze e aggiornare il DOM di conseguenza.
Perché Cambia Tutto
Il vantaggio del pensiero dichiarativo non è solo estetico e di facilità di lettura, bensì è quello per cui non puoi dimenticare un passaggio, proprio perché non stai descrivendo i passaggi, stai descrivendo l'obiettivo. Il codice diventa più leggibile: if (isLoggedIn) return <Benvenuto />; return <Accedi />; si legge quasi come una frase in italiano. E soprattutto smetti di pensare al DOM. Con React non ragioni più in termini di "seleziona, modifica, aggiorna" ma in termini di "quali dati ho e come dovrebbe apparire la UI per questi dati?". Il DOM diventa un dettaglio implementativo di cui React si occupa.
Regola: In React, il tuo lavoro è descrivere il Cosa (che aspetto ha la UI in ogni stato). Il lavoro di React è occuparsi del Come (come arrivare da uno stato all'altro nel DOM).
6. JSX (Il Lupo Travestito da Pecora)
JSX sembra HTML e si comporta quasi come HTML, ma non lo è. Capire la sua vera natura è fondamentale per evitare decine di bug incomprensibili.
JSX Non È HTML (Sotto il Cofano)
Nessun browser al mondo sa interpretare JSX. Tag come <Navbar /> o espressioni come {variabile} non fanno parte di nessuno standard web. Il JSX che scrivi non arriva mai al browser: prima di quel momento, un compilatore come Babel (o quello integrato in Vite) lo traduce interamente in chiamate JavaScript pure.
In pratica, ogni tag JSX viene convertito in una chiamata a React.createElement().
// QUELLO CHE SCRIVI TU (JSX)
const elemento = <h1 className="titolo">Ciao {nome}</h1>;
// QUELLO CHE IL COMPILATORE GENERA (JavaScript puro)
const elemento = React.createElement(
'h1', // tipo del tag
{ className: 'titolo' }, // le props (attributi)
'Ciao ', // primo figlio (testo)
nome // secondo figlio (variabile)
);
JSX è quindi zucchero sintattico: una scrittura visivamente simile all'HTML che il compilatore trasforma in codice JavaScript ordinario. È il lupo (JavaScript) travestito da pecora (HTML).
Il Portale Dimensionale { } (Statico vs. Dinamico)
Le graffe { } in JSX funzionano come un portale tra due mondi. Tutto ciò che scrivi fuori dalle graffe è testo statico, esattamente come nell'HTML tradizionale. Nel momento in cui apri una graffa, entri nel mondo JavaScript e puoi inserire qualsiasi espressione: variabili, calcoli, chiamate a funzione, operatori ternari.
const nomeUtente = "Mario";
const eta = 25;
// Fuori dalle graffe: stringa letterale
<p className="saluto">Benvenuto</p>
// Dentro le graffe: espressioni JavaScript
<p>Ciao, {nomeUtente}!</p> // variabile
<p>Hai {eta} anni</p> // numero
<p>Tra 10 anni avrai {eta + 10} anni</p> // calcolo
<p>{eta >= 18 ? "Maggiorenne" : "Minorenne"}</p> // ternario
La Distinzione Cruciale tra Stringhe e Espressioni nelle Props
// Passa la stringa letterale "2 + 2", nessun calcolo!
<Figlio messaggio="2 + 2" />
// Passa il risultato del calcolo: il numero 4
<Figlio messaggio={2 + 2} />
// Passa il valore della variabile
<Figlio messaggio={messaggio} />
// Passa un booleano true (scritto come prop senza valore)
<Figlio attivo />
// equivale a:
<Figlio attivo={true} />
Il Trucco dell'Interruttore (Come Babel Legge il JSX)
Per capire come JSX e JavaScript possano convivere nello stesso file, è utile sapere come ragiona il compilatore. Babel parte in modalità JavaScript e aspetta espressioni JS normali. Quando incontra un < seguito da una lettera, capisce che sta iniziando un tag e passa in modalità UI (interpreta il markup). Quando incontra una { all'interno del markup, riapre il portale JavaScript per valutare l'espressione. E così via, alternando continuamente le due modalità.
Questo meccanismo è quello che rende possibile scrivere codice come il seguente, dove markup e logica si intrecciano in modo naturale.
function Lista({ elementi }) {
return (
<ul> {/* modalità UI */}
{elementi.map(el => {/* portale JS */}
<li key={el.id}>{el.nome}</li> {/* modalità UI di nuovo */}
)}
</ul>
);
}
className invece di class (Il Problema delle Parole Riservate)
In HTML scrivi <div class="contenitore">, ma in JSX devi scrivere <div className="contenitore">. Il motivo è che JSX si trasforma in oggetti JavaScript, e gli attributi JSX diventano chiavi di quell'oggetto. La parola class in JavaScript è riservata per dichiarare le Classi OOP.
// In JavaScript, 'class' ha già un significato preciso
class Persona {
constructor(nome) {
this.nome = nome;
}
}
Se fosse possibile scrivere { class: "contenitore" } in un oggetto JS, il parser non saprebbe se stai definendo una classe o assegnando uno stile CSS. JSX risolve il conflitto usando className, che è esattamente il nome della proprietà DOM reale che anche JavaScript Vanilla utilizza.
// Anche in JS Vanilla la proprietà si chiama 'className', non 'class'
document.querySelector('div').className = "contenitore";
In altre parole, JSX parla la lingua del DOM JavaScript, non quella dell'HTML.
// ❌ SBAGLIATO in JSX
<div class="contenitore">...</div>
// ✅ CORRETTO in JSX
<div className="contenitore">...</div>
htmlFor invece di for (Lo Stesso Problema)
Lo stesso problema si presenta con l'attributo for dei <label>. Siccome for in JavaScript è la parola riservata per i cicli, in JSX si usa htmlFor.
// ❌ SBAGLIATO in JSX
<label for="email">La tua email:</label>
<input id="email" type="email" />
// ✅ CORRETTO in JSX
<label htmlFor="email">La tua email:</label>
<input id="email" type="email" />
Questo collegamento è fondamentale per l'accessibilità: quando un utente clicca sulla scritta della label, il browser sposta automaticamente il focus all'input collegato. Senza htmlFor, l'utente è costretto a cliccare esattamente sul piccolo campo di testo.
La Trappola delle Parentesi nel return() (ASI)
Può capitare di scrivere un componente che ritorna undefined senza motivo apparente. La causa è quasi sempre l'ASI (Automatic Semicolon Insertion): un meccanismo di JavaScript che inserisce automaticamente un punto e virgola alla fine di certe righe. In particolare, quando il parser vede la parola return seguita da un a capo, assume che il valore di ritorno sia "niente" e chiude la funzione.
// ❌ TRAPPOLA, ASI inserisce ';' subito dopo 'return'
function Saluto() {
return // JavaScript legge: return; la funzione finisce qui!
<h1>Ciao</h1>; // Questo codice non viene mai raggiunto
}
// Risultato: la funzione ritorna 'undefined'
La soluzione è aprire le parentesi tonde sulla stessa riga di return. In questo modo JavaScript capisce che l'espressione non è ancora terminata e continua a leggere fino alla parentesi di chiusura.
// ✅ CORRETTO, le parentesi tengono tutto insieme
function Saluto() {
return ( // JavaScript legge: return (... e aspetta la parentesi di chiusura
<h1>Ciao</h1>
);
}
Regola: appena il JSX del tuo return va su più righe, usa sempre le parentesi tonde.
Fragment <>, la Busta della Spesa Invisibile
Un componente React è una funzione, e una funzione JavaScript può restituire un solo valore. Questo significa che non puoi restituire due elementi JSX fratelli direttamente.
// ❌ ERRORE, stai tentando di restituire due elementi
function DueTitoli() {
return (
<h1>Titolo Principale</h1>
<h2>Sottotitolo</h2>
);
}
La soluzione istintiva è avvolgere tutto in un <div>, ma questo aggiunge un nodo in più al DOM che può rompere layout Flexbox o Grid e complicare i selettori CSS.
// Funziona, ma "sporca" il DOM con un div inutile
function DueTitoli() {
return (
<div>
<h1>Titolo Principale</h1>
<h2>Sottotitolo</h2>
</div>
);
}
Il Fragment risolve il problema in modo pulito: raggruppa gli elementi per soddisfare la regola del "singolo valore di ritorno", ma una volta nel browser sparisce completamente senza lasciare traccia nel DOM. È come una busta della spesa trasparente che raggruppa i prodotti per il trasporto e poi si dissolve.
// ✅ CORRETTO, il Fragment raggruppa senza aggiungere nodi al DOM
function DueTitoli() {
return (
<>
<h1>Titolo Principale</h1>
<h2>Sottotitolo</h2>
</>
);
}
La sintassi breve <>...</> copre la quasi totalità dei casi. L'unica eccezione è quando devi passare una prop key (nelle liste): la sintassi breve non accetta attributi, quindi serve la forma esplicita <React.Fragment key={...}>.
// La sintassi lunga serve solo quando hai bisogno di key
{items.map(item => (
<React.Fragment key={item.id}>
<dt>{item.termine}</dt>
<dd>{item.definizione}</dd>
</React.Fragment>
))}
Le Doppie Graffe {{ }}, Non È una Sintassi Speciale
Vedendo style={{ color: 'red' }} per la prima volta, potresti pensare che {{ }} sia una sintassi speciale di React per gli stili. In realtà sono semplicemente due costrutti sovrapposti: la prima graffa { apre il portale JavaScript (come abbiamo visto precedentemente), e la seconda graffa { inizia un normale oggetto JavaScript letterale. Il risultato visivo sono due graffe consecutive, ma concettualmente è un oggetto dentro un portale.
// Queste due scritture sono identiche
// Scrittura compatta (le "doppie graffe")
<div style={{ backgroundColor: 'rosso', fontSize: 16 }}>...</div>
// Scrittura esplicita (più chiara per capire cosa succede)
const mioStile = { backgroundColor: 'rosso', fontSize: 16 };
<div style={mioStile}>...</div>
La stessa logica si applica ogni volta che passi un oggetto come prop.
<Componente configurazione={{ tema: 'scuro', lingua: 'it' }} />
// { esterna = apre il portale JS
// { interna = inizio dell'oggetto JS
// } interna = fine dell'oggetto JS
// } esterna = chiude il portale
Sicurezza by Default (dangerouslySetInnerHTML)
JSX ha una protezione contro gli attacchi XSS (Cross-Site Scripting) incorporata. Quando inserisci un valore dentro { }, React lo sanitizza automaticamente prima di renderizzarlo: converte caratteri potenzialmente pericolosi come <, >, " e & in entità HTML sicure. Questo significa che anche se un utente malintenzionato inserisce codice malevolo in un campo di testo, React lo trasforma in testo innocuo.
const inputUtente = "<script>alert('Hacked!')</script>";
// React sanitizza automaticamente, nessun pericolo
<p>{inputUtente}</p>
// Il browser mostra letteralmente: <script>alert('Hacked!')</script>
// Lo script NON viene eseguito
L'unico modo per aggirare questa protezione è usare la prop dangerouslySetInnerHTML, il cui nome è intenzionalmente spaventoso. React vuole che tu sia consapevole di star disabilitando le protezioni di sicurezza ogni volta che la usi.
// ⚠️ PERICOLOSO, usa solo con HTML che controlli al 100%
<div dangerouslySetInnerHTML={{ __html: htmlFidatoDelServer }} />
Regola: Usa dangerouslySetInnerHTML solo per HTML generato da te stesso o da un sistema fidato come un CMS che sanitizza i contenuti in autonomia. Mai con input dell'utente o dati da fonti non verificate.