JSX è un’estensione di sintassi simile a XML per JavaScript, sviluppata dal team di React per descrivere dichiarativamente le interfacce utente. A differenza dei motori di template, JSX viene compilato in normali chiamate a funzioni JavaScript, dando la piena potenza del linguaggio all’interno del markup. Secondo React, 2024, JSX è supportato in tutti i framework e le librerie React moderni.
Punti chiave
JSX (JavaScript XML) è un’estensione sintattica per JavaScript, introdotta per la prima volta in React nel 2013. Consente agli sviluppatori di descrivere la struttura di un’interfaccia utente in modo dichiarativo, combinando markup e logica in un singolo file.
Prima di JSX, gli sviluppatori utilizzavano template di stringhe (Mustache, Handlebars) o creavano elementi DOM manualmente tramite document.createElement. Entrambi gli approcci avevano svantaggi: i template di stringhe non erano controllati dai tipi e la creazione manuale del DOM era complessa e soggetta a errori.
React ha scelto una strada diversa — incorporare il markup direttamente nel codice. Questa decisione ha suscitato dibattiti nella comunità, ma col tempo è diventata lo standard. Oggi JSX viene utilizzato non solo in React, ma anche in SolidJS, Preact, Qwik e persino in Vue tramite plugin.
Un elemento JSX assomiglia a un tag HTML ma è incorporato direttamente in JavaScript. Ogni elemento viene trasposto in una chiamata React.createElement con tre argomenti: tipo di elemento, oggetto props e figli. Un elemento radice è una regola obbligatoria: un’espressione JSX deve restituire un elemento padre o un frammento.
import React from 'react';
// JSX di base - elemento radice singolo
const element = (
<div className="app">
<h1>Hello, World!</h1>
<p>Welcome to React</p>
</div>
);
Quando non serve un nodo DOM aggiuntivo, usa React.Fragment o la sintassi abbreviata <></>. I frammenti non creano un elemento DOM reale, ma raggruppano solo i nodi figli. Ciò è particolarmente utile in tabelle e liste dove un wrapper extra romperebbe la struttura HTML.
function Columns() {
return (
<>
<td>First</td>
<td>Second</td>
</>
);
}
Qualsiasi espressione JavaScript viene incorporata in JSX tramite parentesi graffe { }. All’interno, puoi usare variabili, chiamate a funzioni, operatori ternari e metodi degli array. Il rendering condizionale viene eseguito tramite l’operatore ternario o AND logico.
function Greeting({ name, isLoggedIn }) {
const items = ['Red', 'Green', 'Blue'];
return (
<div>
{/* Expression with variable */}
<h1>Hello, {name}</h1>
{/* Conditional rendering */}
{isLoggedIn ?
<p>Welcome back!</p :
<button>Login</button>
}
{/* Render array */}
<ul>
{items.map(item =>
<li key={item}>{item}</li>
)}
</ul>
</div>
);
}
Una limitazione chiave — solo le espressioni possono essere usate all’interno delle parentesi graffe, non le istruzioni. Non puoi usare if/else, for, switch — solo l’operatore ternario, operatori logici e metodi degli array. Le chiamate a funzione sono consentite, incluse le funzioni freccia.
JSX assomiglia visivamente a HTML ma ha differenze fondamentali. Gli attributi si scrivono in camelCase — className invece di class, onClick invece di onclick, tabIndex invece di tabindex. Ciò è dovuto al fatto che JSX si transpila in JavaScript, dove i trattini nei nomi delle proprietà non sono consentiti.
| HTML | JSX | Motivo |
|---|---|---|
class="wrapper" | className="wrapper" | class è parola riservata in JS |
onclick="handle()" | onClick={handle} | camelCase per proprietà JS |
style="color: red" | style={{ color: ‘red’ }} | Oggetto stile invece di stringa |
<input disabled> | <input disabled={true}> | Attributi booleani espliciti |
Un’altra differenza importante — tag auto-chiudenti. In HTML, alcuni tag (br, hr, input) possono rimanere aperti. In JSX, tutti i tag auto-chiudenti devono avere una barra di chiusura: <br />, <input />. Anche i nomi degli attributi SVG vengono convertiti in camelCase: strokeWidth, fillOpacity.
I browser non comprendono JSX direttamente. Prima dell’esecuzione, il codice JSX passa attraverso un transpilatore — Babel, TypeScript o esbuild. Ogni elemento JSX viene trasformato in una chiamata createElement o jsx/runtime.
// JSX originale
const element = <h1 className="title">Hello</h1>;
// Dopo la transpilazione
const element = React.createElement(
'h1',
{ className: 'title' },
'Hello'
);
Con React 17 è apparsa una nuova trasformazione JSX che non richiede l’importazione di React. L’importazione automatica di jsx-runtime consente di scrivere componenti senza import React from ‘react’. Babel e TypeScript supportano questa trasformazione tramite la configurazione {"runtime": "automatic"}.
Sebbene JSX sia associato a React, anche altri framework lo utilizzano. SolidJS usa JSX con compilazione in nodi DOM reali, senza Virtual DOM. Preact è un’alternativa leggera a React con pieno supporto JSX. Vue supporta JSX tramite @vue/babel-plugin-jsx, sebbene il suo template principale sia template.
Una differenza chiave è la semantica delle espressioni. In React, le espressioni JSX vengono eseguite a ogni rendering. In SolidJS, JSX viene compilato una volta e gli aggiornamenti vengono tracciati tramite segnali. Ciò influisce sulle prestazioni: SolidJS non richiede Virtual DOM e riconciliazione, rendendo il rendering JSX più veloce.
In TypeScript, JSX è supportato a livello di linguaggio. I file con estensione .tsx gestiscono automaticamente la sintassi JSX. La tipizzazione delle props è uno dei principali vantaggi di TypeScript + JSX: l’IDE suggerisce gli attributi attesi, i tipi di callback e l’obbligatorietà delle props.
Scrivi codice JSX facile da leggere e mantenere. Estrai le espressioni complesse in variabili o funzioni separate — questo migliora la leggibilità e consente di testare la logica separatamente dal markup. Usa frammenti invece di wrapper div inutili.
La regola di indentazione — mantieni l’indentazione per gli elementi annidati. Ogni livello di annidamento è un livello di indentazione. Il tag di chiusura deve essere allo stesso livello del tag di apertura. Per attributi lunghi, usa interruzioni di riga.
Evita le funzioni freccia inline nelle props se vengono create a ogni rendering. In questi casi, avvolgi il callback in useCallback o sposta la funzione fuori dal componente. Dividi i componenti complessi in più piccoli — ogni componente dovrebbe gestire un’unità logica dell’interfaccia.
Domande frequenti
Sì, tramite il plugin Babel @babel/plugin-transform-react-jsx, JSX può essere configurato per qualsiasi libreria. SolidJS, Preact, Nerv e altri framework usano JSX con i propri runtime. Per completa indipendenza, puoi impostare il pragma sulla tua funzione.
class è una parola riservata in JavaScript. JSX si transpila in createElement, dove il secondo argomento passa un oggetto props. La proprietà class entra in conflitto con la sintassi delle classi ES6, quindi React ha scelto className.
Usa i template string o la libreria classnames: className={`btn ${isActive ? ‘active’ : ‘’}`}. Per logica complessa, installa il pacchetto npm clsx o classnames, che accettano oggetti e array.
JSX supporta solo espressioni, non istruzioni. Per le condizioni, usa l’operatore ternario, AND logico (&&) o OR logico (||). Per logica complessa, estrai la condizione in una variabile o funzione separata.
L’attributo key aiuta React a identificare gli elementi della lista durante il re-rendering. Senza key, React ri-rende l’intera lista al cambiamento. Con una key univoca, React riutilizza i nodi DOM e riordina gli elementi invece di ricrearli.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche