Realizzare UI con React - 5. Creare Elementi e JSX
Tags: react
Published: 2020-09-06 22:11:43

---
title: Realizzare UI con React - 5. Creare Elementi e JSX
published: true
date: 2020-09-05 08:09:00 UTC
tags: React
canonical_url: https://www.matteospreafico.com/realizzare-ui-con-react-5-creare-elementi-e-jsx/
series: Corso di React
description: In React usiamo degli oggetti JavaScript chiamati Elementi per descrivere come vogliamo che sia la pagina e poi React si occupa di applicare le modifiche al DOM per ottenere il risultato.
---

In React usiamo degli oggetti JavaScript chiamati Elementi per descrivere come vogliamo che sia la pagina e poi React si occupa di applicare le modifiche al DOM per ottenere il risultato.

## Disegnare Elementi React nel DOM

Invece di usare template per descrivere l'interfaccia utente, React usa gli elementi. Vediamo cos'è un elemento in React con il seguente esempio dove a sinistra potete vedere il codice ed a destra il risultato nel browser.

<iframe width="1280" height="500" src="https://codesandbox.io/embed/disegnare-elementi-nel-dom-1-6lkmv?fontsize=14&amp;hidenavigation=1&amp;theme=dark" style="width:1280px; height:500px; border:0; border-radius: 4px; overflow:hidden;" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"></iframe><figcaption>Esempio di elemento in React</figcaption>

Nell'editor ho creato un nuovo elemento in React usando `React.CreateElement`. Questa è un API di primo livello di React per creare elementi, assomiglia al metodo per creare elementi dell'oggetto `document` ma è leggermento diverso. Il primo argomento è il nome del tag dell'elemento che vogliamo usare, nel nostro caso `"div"`. Il secondo argomento lo vedremo in seguito ed il terzo è il testo che vogliamo inserire all'interno del div.

Ma come inseriamo questo elemento nella pagina? Per fare questo dobbiamo usare `ReactDOM`. In React, il processo per decidere cosa disegnare è completamente separato da quello che effettivamente si occupa di disegnarlo. Questa separazione rende possibile generare le pagine sul server oppure nativamente sui dispositivi mobile ed anche nella realtà virtuale. In questo esempio usiamo `ReactDOM` perché siamo lavorando nel browser. Nel esempio, uso il metodo `ReactDOM.render` posso disegnare il mio elemento nella pagina, nell'elemento del DOM chiamato `root`.

Per vedere cosa è effettivamente l'elemento React che ho creato, potete usare `console.log(elemento)`. Come potete notare, si tratta semplicemente do un oggetto JavaScript, con una serie di diverse proprietà.

```
{
    type: "div",
    key: null,
    ref: nul,
    props: Object,
    children: "Ciao Mondo!",
    _owner: null,
    _store: Object
}
```
<figcaption>Risultato di <code>console.log(elemento)</code></figcaption>

Quando abbiamo deciso di inserire nella pagina il nostro elemento React, abbiamo usato l'elemento del DOM chiamato `root`, ma da dove arriva questo elemento?  
Solitamente le applicazioni React hanno un elemento DOM nella pagina chiamato `root`, un HTML di esempio è il seguente:

```
<div id="root"></div>
```
<figcaption>Esempio di HTML che ospita un'applicazione React</figcaption>

Passando a `ReactDOM` questo elemento del DOM usando il metodo `getElementById()`, React è in grado di prendere il controllo del suo contenuto.

Ora vediamo come aggiungere una classe CSS al nostro elemento. Usiamo il secondo argomento di `React.createElement` che prima abbiamo saltato, come potete vedere nel seguente esempio

<iframe width="1280" height="500" src="https://codesandbox.io/embed/disegnare-elementi-react-nel-dom-con-una-classe-n43tk?fontsize=14&amp;hidenavigation=1&amp;theme=dark" style="width:1280px; height:500px; border:0; border-radius: 4px; overflow:hidden;" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"></iframe><figcaption>Esempio di elemento in React con classe CSS</figcaption>

Come potete vedere, non ho usato la parola `class` per descrivere la classe CSS, ma invece la proprietà si chiama `className`. Questo potrebbe generare della confusione, ma dobbiamo tenere a mente che stiamo descrivendo nodi del DOM e non HTML. Se ora esploriamo il codice HTML generato, vedremo che questo contiene un div con un attributo `class`

```
<div class="messaggio-di-benvenuto">Ciao Mondo!</div>
```
<figcaption>HTML generato dal elemento React con classe CSS</figcaption>

Probabilmente avrete già sentito il termine _DOM Virtuale_ ( _Virtual DOM_ ) mentre stavate cercando informazioni su React. Quello che questo termine significa è che questi elementi React che stiamo creando, non sono veri elementi del DOM, sono invece oggetti che descrivono elementi del DOM. Quando quindi chiamiamo `React.createElement` non abbiamo ancora creato niente nel DOM. Solo quando chiamiamo `ReactDom.render` il browser create gli elementi DOM necessari.

## `React.createElement()` restituisce un Elemento React

Abbiamo usato il metodo `React.createElement()` per creare e restituire un nuovo elemento React, vediamo qual è la sua dichiarazione:

```
React.createElement(
  type,
  [props],
  [...children]
)
```
<figcaption>Dichiarazione di <code>React.createElement()</code></figcaption>

Accetta tre argomenti:

- `type`: può essere il nome di un tag (ad esempio 'div' o 'span') o un componente React,
- `props`: può essere null oppure un oggetto con degli attributi HTML o dati per l'elemento,
- `...children`: qualunque cosa venga passata qui, sarà usata come contenuto dell'elemento. Possiamo usare stringhe, JavaScript od anche altri elementi React.

Vediamo quindi come annidare un elemento React dentro l'altro in questo esempio:

<iframe width="1280" height="500" src="https://codesandbox.io/embed/disegnare-elementi-react-nel-dom-annidati-pkzb8?fontsize=14&amp;hidenavigation=1&amp;theme=dark" style="width:1280px; height:500px; border:0; border-radius: 4px; overflow:hidden;" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"></iframe><figcaption>Esempio di elementi React annidati</figcaption>

Abbiamo cambiamo il tag da 'div' ad 'ul' per creare una lista e sostituito la stringa "Ciao Mondo!" con un array che contiene degli elementi React creati con `React.createElement()` che usano il tag 'li' per gli elementi della lista.

Se notate, c'è un avviso nella Console, React si sta lamentando che gli elementi nell'array non hanno una proprietà `key` univoca. Cosa vuol dire?  
Come quando abbiamo aggiunto la classe CSS all'elemento, possiamo aggiungere ad ogni elemento React nel secondo argomento di `React.createElement()`. Qualcosa di unico per ognuno di questi elementi, in questo caso potremmo usare il nome.

Stiamo anche duplicando il codice al momento, per ogni elemento annidato usiamo la stessa chiamata a `React.createElement()` con una persona diversa. Potremmo usare JavaScript per generare questi elementi usando il metodo `.map()` su una array che contiene le persone. Non ci serve un sistema di template o una sintassi speciale, possiamo usare direttamente JavaScript senza dover imparare nulla di nuovo. Vediamo il risultato:

<iframe width="1280" height="500" src="https://codesandbox.io/embed/disegnare-elementi-react-nel-dom-annidati-da-array-colmw?fontsize=14&amp;hidenavigation=1&amp;theme=dark" style="width:1280px; height:500px; border:0; border-radius: 4px; overflow:hidden;" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"></iframe><figcaption>Esempio di elementi React annidati con <code>Array.map()</code></figcaption>

## Anche JSX restituisce un Elemento

Abbiamo visto come creare elementi e come annidarli, ma se dovessimo usare queste chiamate per creare un'applicazione non banale, sarebbe alquanto problematico. Servirebbe una sintassi diversa, pensata per descrivere relazione tra elementi in modo più naturale... come ad esempio HTML! Fa esattamente questo!

Come possiamo far sembrare il nostro metodo `React.createElement()` più simile ad HTML? JSX è un'estensione di JavaScript che fa esattamente questo. Ci permette di scrivere del codice JavaScript che sembra HTML  lo rende più stringato e facile da leggere.

Modifichiamo il nostro esempio per usare JSX

<iframe width="1280" height="500" src="https://codesandbox.io/embed/disegnare-elementi-react-nel-dom-con-jsx-t0ly5?fontsize=14&amp;hidenavigation=1&amp;theme=dark" style="width:1280px; height:500px; border:0; border-radius: 4px; overflow:hidden;" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"></iframe><figcaption>Esempio di elementi React con JSX</figcaption>

Al posto del primo `React.createElement()` abbiamo usato `<ul>` ed al suo interno abbiamo usato le parentesi graffe per indicare che un blocco di JavaScript puro, senza JSX, dove abbiamo la chiamata a `.map()`. Per ogni persona poi usiamo ancora JSX con un `<li>` per gli elementi della lista e di nuovo usiamo le parentesi graffe per indicare dei valori JavaScript, sia per la proprietà `key` che prima passavamo come secondo parametro che per il contenuto dell'elemento stesso.

Molte persone restano disorientate la prima volta che vedono questa sintassi, ma non dovete preoccuparvi, è una reazione molto comune, notate piuttosto come il codice è molto più snello.

Quando scriviamo JSX dobbiamo però ricordarci che deve restituire un singolo elemento. Possiamo avere un qualunque numero di elementi annidati, ma alla radice deve esserci un singolo elemento.

```
const message = (
 <div>
 <h1>JSX in sintesi:</h1>
 <ul>
 <li>JSX</li>
 <li>è</li>
 <li>stupendo!</li>
 </ul>
 </div>
);
```
<figcaption>Esempio di JSX</figcaption>

L'esempio di JSX precedente è valido perché c'è singolo nodo `<div>` che contiene tutti gli altri, mentre il seguente esempio NON è valido:

```
const message = (
 <h1>JSX in sintesi:</h1>
 <ul>
 <li>JSX</li>
 <li>è</li>
 <li>stupendo!</li>
 </ul>
);
```
<figcaption>Esempio di JSX NON valido</figcaption>

In questo esempio potete notare che sia l'elemento `<h1>` che l'elemento `<ul>` sono al livello radice. Questo codice non funzionerà e avrete un messaggio di questo tipo:

> Syntax error: Adjacent JSX elements must be wrapped in an enclosing tag

Dato che sappia che JSX non è che un'estensione di `React.createElement()` questo errore ha senso, perché questo metodo accetta come primo parametro un singolo nome per il tag.

## Componenti

Per ora abbiamo visto come usare `React.createElement()` e JSX per creare HTML, ma in React solitamente si usano i Componenti per costruire l'interfaccia utente. I Componenti sono dei blocchi di codice riutilizzabili che sono responsabili di restituire del HTML usato per disegnare la pagina. Molto spesso i Componenti React sono scritti usando JSX.

Dato che l'obiettivo principale di React è realizzare l'interfaccia utente, c'è solo un metodo che è assolutamente necessario in ogni Classe Componente React: `render()`. Si possono usare anche i Componenti Funzioni in React, in modo del tutto equivalente alle Classi Componente; in questo caso la funzione deve ovviamente restituire l'HTML da usare per disegnare la pagina.

<iframe width="1280" height="500" src="https://codesandbox.io/embed/disegnare-elementi-react-nel-dom-con-classe-componente-1hnhc?fontsize=14&amp;hidenavigation=1&amp;theme=dark" style="width:1280px; height:500px; border:0; border-radius: 4px; overflow:hidden;" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"></iframe><figcaption>Disegnare Elementi React nel DOM con Classe Componente</figcaption>

<iframe width="1280" height="500" src="https://codesandbox.io/embed/disegnare-elementi-react-nel-dom-con-componente-funzione-ii96q?fontsize=14&amp;hidenavigation=1&amp;theme=dark" style="width:1280px; height:500px; border:0; border-radius: 4px; overflow:hidden;" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"></iframe><figcaption>Disegnare Elementi React nel DOM con Componente Funzione</figcaption>

Ricordiamoci che React si occupa solo della livello di presentazione della nostra applicazione, quello che l'utente vede e con cui interagisce. I Componenti rappresentano la modularità e riusabilità di React e dovrebbero seguire il [principio di singola responsabilità](https://it.wikipedia.org/wiki/Principio_di_singola_responsabilit%C3%A0) e fare solo una cosa.