JSX, acronimo di JavaScript XML, è un’estensione della sintassi di React che permette agli sviluppatori di scrivere codice simile all’HTML nei loro file JavaScript.

Quando si lavora con JSX, i principianti si imbattono spesso in un errore comune che dice: “JSX expressions must have one parent element” (JSX expressions must have one parent element). Questo errore si verifica quando più elementi vengono restituiti in una singola espressione senza essere avvolti in un elemento genitore.

Questo errore è anche molto simile a “Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>…</>?” (Gli elementi JSX adiacenti devono essere racchiusi in un tag. Volevi un Fragment JSX <>…</>?).

In questo articolo scopriremo le diverse soluzioni da utilizzare per evitare questo ostacolo comune lavorando con React.

Cosa causa l’errore “JSX expressions must have one parent element”?

In JSX esiste una regola che stabilisce che le espressioni devono sempre restituire un singolo elemento. Questa regola si applica a React, il che significa che ogni componente può restituire solo un singolo elemento principale.

Questo perché quando si esegue il rendering di un componente, React crea un albero DOM virtuale che corrisponde all’HTML che viene renderizzato nella pagina. Se ci sono più elementi root nel JSX, React non sa come gestirli, il che si traduce nell’errore “JSX expressions must have one parent element” o “Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment …?”

Ad esempio, se proviamo a renderizzare il seguente codice JSX:

function App() {
    return (
        <h1>Hello, world!</h1>
        <p>This is a paragraph.</p>
    )
}

Otterremo l’errore “JSX expressions must have one parent element”:

Messaggio d'errore JSX expressions must have one parent element
L’errore “JSX expressions must have one parent element”

Oppure l’errore “Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>…</>?”:

Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>? error message
Errore Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>…</>?

Questo perché vengono restituiti due elementi root (<h1> e <p> ).

JSX opera in modo simile a una funzione perché le funzioni non possono restituire più valori (a meno che non siano racchiusi in un array, che viene considerato un unico valore).

function myFunc() {
  return value1;
  return value2;
}

La seconda istruzione di ritorno nella funzione render è irraggiungibile perché la prima istruzione di ritorno verrà sempre eseguita, rendendo impossibile l’esecuzione della seconda.

3 modi per risolvere l’errore “JSX expressions must have one parent element”

Esistono tre metodi principali per risolvere questo errore:

  • Utilizzando un Div Wrapper
  • Utilizzando un Fragment (<> e </>)
  • Utilizzando il componente React.Fragment

1. Avvolgere tutti gli elementi con un Div Wrapper

Una delle soluzioni più semplici all’errore “JSX expressions must have one parent element” è quella di avvolgere gli elementi JSX multipli in un unico elemento genitore, come ad esempio un <div>.

In questo modo è possibile raggruppare e rendere gli elementi come un’unica unità. Ad esempio, considera il componente qui sotto:

function App() {
    return (
        <div>
            <h1>Hello, world!</h1>
           <p>This is a paragraph.</p>
        </div>
    )
}

In questo esempio, gli elementi <h1> e <p> sono racchiusi in un elemento <div>, che funge da elemento genitore.

2. Avvolgere tutti gli elementi con un Fragment

Un altro modo per risolvere il problema “JSX expressions must have one parent element” o “Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>…</>?” è utilizzare un Fragment JSX.

Un Fragment è una funzione integrata di React che permette di raggruppare un elenco di child senza aggiungere altri nodi al DOM. Possiamo utilizzare un Fragment per avvolgere gli elementi multipli in un unico elemento genitore senza aggiungere un nodo DOM supplementare all’HTML renderizzato. Ad esempio, ecco un componente:

function App() {
    return (
        <>
            <h1>Hello, world!</h1>
            <p>This is a paragraph.</p>
        </>
    )
}

In questo esempio, viene utilizzato un Fragment JSX (<> e </>) per avvolgere gli elementi multipli. Questo Fragment funge da elemento genitore.

3. Avvolgere tutti gli elementi con React.Fragment

Infine, un altro modo per risolvere l’errore “JSX expressions must have one parent element” è quello di utilizzare il componente React.Fragment al posto di un normale elemento.

Funziona in modo simile all’utilizzo di un Fragment JSX, ma è un po’ più esplicito e può essere utile se vogliamo dare all’elemento genitore una chiave specifica o altri prop. Ad esempio, ecco un componente:

function App() {
    return (
        <React.Fragment>
            <h1>Hello, world!</h1>
            <p>This is a paragraph.</p>
       </React.Fragment>
    )
}

In questo esempio, il componente React.Fragment viene utilizzato al posto di un normale elemento per fungere da elemento genitore. Il componente avvolge più elementi all’interno dei tag <></>, il che permette di raggruppare gli elementi senza aggiungere un ulteriore nodo all’HTML renderizzato.

Il componente React.Fragment richiede l’importazione di React. Inoltre, permette di aggiungere prop e anche className, style e id al Fragment stesso, il che è utile quando si vogliono applicare stili o altri attributi al gruppo di elementi all’interno del Fragment.

Come risolvere l’errore “JSX expressions must have one parent element” nei condizionali

Quando si lavora con le dichiarazioni condizionali utilizzando gli operatori ternari in React, è comune incontrare il messaggio di errore “JSX expressions must have one parent element” o “Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>…</>?”.

Questo accade quando vengono restituiti più elementi all’interno di un’istruzione condizionale. In questo caso, React non sarà in grado di renderizzarli correttamente e si verificherà uno dei due errori.

function App() {
    return (
        <div>
            {condition ? (
                <h1>Heading 1</h1>
                <p>Paragraph 1</p>
                        ) : (
                <h2>Heading 2</h2>
                <p>Paragraph 2</p>
            )}
        </div>
    )
}

Possiamo risolvere questo errore con uno dei tre metodi spiegati in questo articolo. Possiamo utilizzare il Fragment React (<> e </>) o l’elemento <div>.

function App() {
    return (
        <div>
            {condition ? (
                <>
                    <h1>Heading 1</h1>
                   <p>Paragraph 1</p>
                </>
            ) : (
                <>
                    <h2>Heading 2</h2>
                    <p>Paragraph 2</p>
                </>
            )
            }
        </div>
    )
}

Riepilogo

L’errore “JSX expressions must have one parent element” o “Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>…</>?” è un ostacolo piuttosto comune che i principianti devono affrontare quando imparano React.

L’utilizzo di un wrapper <div> è la soluzione più semplice, ma può aggiungere div non necessari al DOM. I fragment offrono una soluzione più pulita senza aggiungere altri nodi al DOM.

Ora tocca a voi: avete mai incontrato questo problema? Come l’avete risolto? Ci sono altri approcci che avete utilizzato e che non sono stati trattati in questo articolo? Fatecelo sapere nei commenti!