00
:
00
:
00
:
00
Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

JSX: Le Basi

Cos’è JSX?

JSX (JavaScript XML) è un’estensione sintattica di JavaScript che permette di scrivere strutture simili all’HTML direttamente nel codice JavaScript. Non è né una stringa né HTML puro: è una sintassi che viene trasformata in chiamate JavaScript durante la compilazione.

// JSX
const elemento = <h1>Ciao, mondo!</h1>;

// Viene trasformato dal compilatore in:
const elemento = React.createElement("h1", null, "Ciao, mondo!");

JSX è opzionale in React, ma la stragrande maggioranza degli sviluppatori lo utilizza perché rende il codice molto più leggibile e intuitivo.

Regole Fondamentali di JSX

Un Solo Elemento Root

Ogni espressione JSX deve avere un unico elemento radice. Non è possibile restituire elementi fratelli senza un contenitore.

// ERRORE: due elementi radice
function Componente() {
  return (
    <h1>Titolo</h1>
    <p>Paragrafo</p>
  );
}

// CORRETTO: un elemento radice
function Componente() {
  return (
    <div>
      <h1>Titolo</h1>
      <p>Paragrafo</p>
    </div>
  );
}

Tutti i Tag Devono Essere Chiusi

In JSX, ogni tag deve essere chiuso, compresi quelli che in HTML sono self-closing.

// HTML valido, JSX non valido
<img src="foto.jpg">
<br>
<input type="text">

// JSX valido
<img src="foto.jpg" />
<br />
<input type="text" />

CamelCase per gli Attributi

JSX usa il camelCase per gli attributi, non il kebab-case dell’HTML.

// HTML
<div class="container" tabindex="0" onclick="handleClick()">

// JSX
<div className="container" tabIndex={0} onClick={handleClick}>

Espressioni JavaScript in JSX

Le parentesi graffe {} permettono di inserire qualsiasi espressione JavaScript valida all’interno di JSX.

function Profilo() {
  const nome = "Marco";
  const eta = 28;
  const oggi = new Date();

  return (
    <div>
      <h1>{nome}</h1>
      <p>Età: {eta}</p>
      <p>Anno corrente: {oggi.getFullYear()}</p>
      <p>Maggiorenne: {eta >= 18 ? "Sì" : "No"}</p>
      <p>{`Ciao, mi chiamo ${nome} e ho ${eta} anni`}</p>
      <p>Somma: {2 + 2}</p>
    </div>
  );
}

Cosa Si Può Inserire nelle Graffe

Le graffe accettano espressioni, non istruzioni. Ecco la differenza:

// VALIDO: espressioni
{nome}                    // Variabile
{getUtente()}             // Chiamata a funzione
{a + b}                   // Operazione
{condizione ? "sì" : "no"}  // Ternario
{array.map(item => ...)}  // Metodo che ritorna un valore

// NON VALIDO: istruzioni
{if (condizione) { ... }}   // if è un'istruzione
{for (let i = 0; ...) {}}  // for è un'istruzione
{const x = 5}              // dichiarazione

className vs class

In JSX si usa className al posto di class perché class è una parola riservata in JavaScript.

function Card() {
  const isAttiva = true;

  return (
    <div className="card">
      <h2 className="card-titolo">Titolo</h2>
      {/* className dinamica */}
      <div className={`badge ${isAttiva ? "attiva" : "inattiva"}`}>
        Stato
      </div>
    </div>
  );
}

Classi Dinamiche con Template Literal

function Pulsante({ variante, dimensione, disabilitato }) {
  const classi = [
    "btn",
    `btn-${variante}`,
    `btn-${dimensione}`,
    disabilitato && "btn-disabled",
  ]
    .filter(Boolean)
    .join(" ");

  return <button className={classi}>Click</button>;
}

Libreria clsx per Classi Condizionali

import clsx from "clsx";

function Pulsante({ variante, attivo, disabilitato }) {
  return (
    <button
      className={clsx(
        "btn",
        `btn-${variante}`,
        { "btn-attivo": attivo, "btn-disabled": disabilitato }
      )}
    >
      Click
    </button>
  );
}

Stili Inline

In JSX, la prop style accetta un oggetto JavaScript, non una stringa. Le proprietà CSS vanno scritte in camelCase.

function BoxColorato() {
  const stile = {
    backgroundColor: "#3b82f6",
    color: "white",
    padding: "16px",
    borderRadius: "8px",
    fontSize: "18px",
    fontWeight: "bold",
  };

  return <div style={stile}>Box con stile inline</div>;
}

Stili Dinamici

function BarraProgresso({ percentuale }) {
  return (
    <div style={{ width: "100%", backgroundColor: "#e5e7eb", borderRadius: "4px" }}>
      <div
        style={{
          width: `${percentuale}%`,
          height: "20px",
          backgroundColor: percentuale === 100 ? "#22c55e" : "#3b82f6",
          borderRadius: "4px",
          transition: "width 0.3s ease",
        }}
      />
    </div>
  );
}

Quando Usare Stili Inline

Gli stili inline sono utili per valori veramente dinamici (calcolati a runtime). Per stili statici, preferisci CSS Modules, Tailwind o altri approcci.

Fragments

I Fragments permettono di raggruppare elementi senza aggiungere nodi extra al DOM.

import { Fragment } from "react";

// Sintassi completa
function ListaInfo() {
  return (
    <Fragment>
      <h1>Titolo</h1>
      <p>Descrizione</p>
    </Fragment>
  );
}

// Sintassi abbreviata (più comune)
function ListaInfo() {
  return (
    <>
      <h1>Titolo</h1>
      <p>Descrizione</p>
    </>
  );
}

Fragments con Key

Quando si renderizza una lista e serve la prop key, bisogna usare la sintassi completa <Fragment>.

import { Fragment } from "react";

function Glossario({ termini }) {
  return (
    <dl>
      {termini.map((termine) => (
        <Fragment key={termine.id}>
          <dt>{termine.nome}</dt>
          <dd>{termine.definizione}</dd>
        </Fragment>
      ))}
    </dl>
  );
}

Commenti in JSX

Per inserire commenti dentro JSX, si usa la sintassi JavaScript racchiusa tra graffe.

function Componente() {
  return (
    <div>
      {/* Questo è un commento in JSX */}
      <h1>Titolo</h1>

      {/*
        Commento
        su più righe
      */}
      <p>Paragrafo</p>

      {/* I commenti HTML <!-- --> NON funzionano in JSX */}
    </div>
  );
}

Attributi HTML Comuni in JSX

Ecco le differenze principali tra attributi HTML e JSX.

HTML JSX Note
class className class è riservata in JS
for htmlFor for è riservata in JS
tabindex tabIndex camelCase
onclick onClick camelCase, funzione non stringa
readonly readOnly camelCase
maxlength maxLength camelCase
style="color: red" style={{ color: "red" }} Oggetto, non stringa

Rendering di Valori Speciali

JSX ignora alcuni valori durante il rendering, il che è utile per il rendering condizionale ma può causare bug imprevisti.

function EsempiRendering() {
  return (
    <div>
      {/* Vengono renderizzati normalmente */}
      {"stringa"}        {/* "stringa" */}
      {42}               {/* "42" */}
      {3.14}             {/* "3.14" */}

      {/* Vengono IGNORATI (non renderizzati) */}
      {true}             {/* nulla */}
      {false}            {/* nulla */}
      {null}             {/* nulla */}
      {undefined}        {/* nulla */}

      {/* ATTENZIONE: 0 viene renderizzato! */}
      {0}                {/* "0" */}
      {0 && <p>Testo</p>}  {/* Mostra "0", non nulla! */}

      {/* Soluzione: convertire a booleano */}
      {!!0 && <p>Testo</p>}     {/* nulla */}
      {items.length > 0 && <p>Testo</p>}  {/* nulla se array vuoto */}
    </div>
  );
}

JSX e Sicurezza

React escapa automaticamente i valori inseriti in JSX, proteggendo dall’XSS (Cross-Site Scripting).

function ComponenteSicuro() {
  // Questo testo verrà mostrato letteralmente, non eseguito come HTML
  const inputUtente = '<script>alert("hack")</script>';

  return <div>{inputUtente}</div>;
  // Renderizza: <script>alert("hack")</script> (come testo)
}

Se hai davvero bisogno di inserire HTML raw (da una fonte fidata), usa dangerouslySetInnerHTML.

function ArticoloBlog({ contenutoHtml }) {
  // Usa con estrema cautela: solo con contenuto fidato e sanitizzato
  return <div dangerouslySetInnerHTML={{ __html: contenutoHtml }} />;
}

JSX è il cuore della sintassi React. Ricorda le regole fondamentali: un solo elemento radice, tag sempre chiusi, className al posto di class, stili come oggetti, e parentesi graffe per le espressioni JavaScript. I Fragments permettono di evitare wrapper inutili, e React protegge automaticamente dall’XSS. Padroneggiare JSX è il primo passo per scrivere componenti React efficaci.