Scrivere Markup con JSX

JSX è un’estensione della sintassi JavaScript che consente di scrivere markup simile all’HTML all’interno di un file JavaScript. Sebbene esistano altri modi per scrivere i componenti, la maggior parte degli sviluppatori React preferisce la concisione di JSX, e la maggior parte dei codebase lo utilizza.

Imparerai

  • Perché React mescola markup e logica di rendering
  • Come JSX differisce dall’HTML
  • Come visualizzare le informazioni con JSX

JSX: Inserire il markup in JavaScript

Il Web è stato costruito su HTML, CSS e JavaScript. Per molti anni, gli sviluppatori Web hanno tenuto il contenuto in HTML, il design in CSS e la logica in JavaScript, spesso in file separati! Il contenuto veniva marcato all’interno dell’HTML mentre la logica della pagina viveva separata in JavaScript:

HTML markup with purple background and a div with two child tags: p and form.
HTML markup with purple background and a div with two child tags: p and form.

HTML

Three JavaScript handlers with yellow background: onSubmit, onLogin, and onClick.
Three JavaScript handlers with yellow background: onSubmit, onLogin, and onClick.

JavaScript

Ma mentre il Web diventava sempre più interattivo, la logica determinava sempre più il contenuto. JavaScript era responsabile dell’HTML! Ecco perché in React, la logica di rendering e il markup vivono insieme nello stesso posto, ovvero nei componenti.

React component with HTML and JavaScript from previous examples mixed. Function name is Sidebar which calls the function isLoggedIn, highlighted in yellow. Nested inside the function highlighted in purple is the p tag from before, and a Form tag referencing the component shown in the next diagram.
React component with HTML and JavaScript from previous examples mixed. Function name is Sidebar which calls the function isLoggedIn, highlighted in yellow. Nested inside the function highlighted in purple is the p tag from before, and a Form tag referencing the component shown in the next diagram.

Componente React Sidebar.js

React component with HTML and JavaScript from previous examples mixed. Function name is Form containing two handlers onClick and onSubmit highlighted in yellow. Following the handlers is HTML highlighted in purple. The HTML contains a form element with a nested input element, each with an onClick prop.
React component with HTML and JavaScript from previous examples mixed. Function name is Form containing two handlers onClick and onSubmit highlighted in yellow. Following the handlers is HTML highlighted in purple. The HTML contains a form element with a nested input element, each with an onClick prop.

Componente React Form.js

Mantenere la logica di rendering e il markup di un pulsante insieme garantisce che rimangano sincronizzati ogni volta che vengono modificati. Al contrario, i dettagli non correlati, come il markup di un pulsante e il markup di una barra laterale, sono isolati l’uno dall’altro, rendendo più sicuro modificare ognuno di essi da solo.

Ogni componente React è una funzione JavaScript che può contenere del markup che React renderizza nel browser. I componenti React utilizzano un’estensione di sintassi chiamata JSX per rappresentare quel markup. JSX assomiglia molto all’HTML, ma è un po’ più rigoroso e può visualizzare informazioni dinamiche. La migliore maniera per comprenderlo è quella di convertire un po’ di markup HTML in markup JSX.

Nota

JSX e React sono due cose separate. Sono spesso utilizzati insieme, ma puoi utilizzarli indipendentemente l’uno dall’altro. JSX è un’estensione di sintassi, mentre React è una libreria JavaScript.

Convertire HTML in JSX

Supponiamo di avere qualche HTML (perfettamente valido):

<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
<li>Invent new traffic lights
<li>Rehearse a movie scene
<li>Improve the spectrum technology
</ul>

E di volerlo inserire nel nostro componente:

export default function TodoList() {
return (
// ???
)
}

Se lo copiamo e incolliamo così com’è, non funzionerà:

export default function TodoList() {
  return (
    // This doesn't quite work!
    <h1>Hedy Lamarr's Todos</h1>
    <img 
      src="https://i.imgur.com/yXOvdOSs.jpg" 
      alt="Hedy Lamarr" 
      class="photo"
    >
    <ul>
      <li>Invent new traffic lights
      <li>Rehearse a movie scene
      <li>Improve the spectrum technology
    </ul>

Ciò è dovuto al fatto che JSX è più rigoroso e ha alcune regole in più rispetto a HTML! Se leggi i messaggi di errore sopra, ti guideranno nella correzione del markup o puoi seguire la guida di seguito.

Nota

La maggior parte delle volte, i messaggi di errore di React ti aiuteranno a trovare il problema. Leggili se ti blocchi!

Le Regole di JSX

1. Restituisci un singolo elemento root

Per restituire più elementi da un componente, utilizza un tag padre per wrapparli

Per esempio, puoi usare un <div>:

<div>
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
...
</ul>
</div>

Se non vuoi aggiungere un ulteriore <div> al tuo markup, puoi scrivere invece <> e </>:

<>
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
...
</ul>
</>

Questo tag vuoto è chiamato Fragment. I fragments ti consentono di raggruppare elementi senza lasciare traccia nell’albero HTML del browser.

Approfondimento

Perché i tag JSX multipli devono essere wrappati?

JSX sembra HTML, ma sotto il cofano viene trasformato in semplici oggetti JavaScript. Non è possibile restituire due oggetti da una funzione senza wrapparli in un array. Questo spiega perché non è possibile restituire due tag JSX senza wrapparli in un altro tag o in un Fragment.

2. Chiudi tutti i tag

JSX richiede che i tag vengano chiusi esplicitamente: i tag auto-chiusi come <img> devono diventare <img />, e i tag di wrapping come <li>oranges devono essere scritti come <li>oranges</li>.

Ecco come appaiono chiusi l’immagine di Hedy Lamarr e gli elementi della lista:

<>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
/>
<ul>
<li>Invent new traffic lights</li>
<li>Rehearse a movie scene</li>
<li>Improve the spectrum technology</li>
</ul>
</>

3. Scrivi in camelCase quasi tutte le cose!

JSX diventa JavaScript e gli attributi scritti in JSX diventano chiavi degli oggetti JavaScript. Nei propri componenti, spesso si vorrà leggere questi attributi in variabili. Ma JavaScript ha limitazioni sui nomi delle variabili. Ad esempio, i loro nomi non possono contenere trattini o essere parole riservate come class.

Ecco perché in React molti attributi HTML e SVG sono scritti in camelCase. Ad esempio, invece di stroke-width si usa strokeWidth. Poiché class è una parola riservata, in React si scrive className invece, nominata in base alla corrispondente proprietà DOM:

<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
className="photo"
/>

Puoi trovare tutti questi attributi nell’elenco delle props del componente DOM. Se ne sbagli uno, non preoccuparti: React stamperà un messaggio con una possibile correzione nella console del browser.

Insidia

Per ragioni storiche, gli attributi aria-* e data-* sono scritti come in HTML con i trattini.

Pro-tip: Usa un Convertitore JSX

Convertire tutti questi attributi nel markup esistente può essere noioso! Raccomandiamo di utilizzare un convertitore per tradurre il tuo HTML e SVG esistenti in JSX. I convertitori sono molto utili nella pratica, ma è comunque utile capire cosa succede in modo da poter scrivere JSX autonomamente.

Ecco il tuo risultato finale:

export default function TodoList() {
  return (
    <>
      <h1>Hedy Lamarr's Todos</h1>
      <img 
        src="https://i.imgur.com/yXOvdOSs.jpg" 
        alt="Hedy Lamarr" 
        className="photo" 
      />
      <ul>
        <li>Invent new traffic lights</li>
        <li>Rehearse a movie scene</li>
        <li>Improve the spectrum technology</li>
      </ul>
    </>
  );
}

Riepilogo

Ora sai perché JSX esiste e come usarlo nei componenti:

  • I componenti React raggruppano la logica di rendering insieme al markup poiché sono correlati.
  • JSX è simile all’HTML, con alcune differenze. Puoi usare un convertitore se ne hai bisogno.
  • I messaggi di errore spesso ti indirizzeranno nella giusta direzione per correggere il tuo markup.

Sfida 1 di 1:
Converti un po’ di HTML in JSX

Questo HTML è stato copiato in un componente, ma non è un JSX valido. Correggilo:

export default function Bio() {
  return (
    <div class="intro">
      <h1>Welcome to my website!</h1>
    </div>
    <p class="summary">
      You can find my thoughts here.
      <br><br>
      <b>And <i>pictures</b></i> of scientists!
    </p>
  );
}

Che tu lo faccia a mano o usando il convertitore, dipende da te!