Renderizzazione Condizionale
I tuoi componenti dovranno spesso mostrare cose differenti a seconda di diverse condizioni. In React, puoi renderizzare condizionalmente JSX usando la sintassi JavaScript con istruzioni come if
, &&
e gli operatori ? :
.
Imparerai
- Come ritornare JSX differenti a seconda di una condizione
- Come includere o escludere condizionalmente una porzione di JSX
- Comuni scorciatoie di sintassi condizionale che incontrerai nele basi di codice React
Ritornare JSX condizionalmente
Immagina di avere un componente PackingList
che renderizza diversi Item
, i quali possono essere marcati come imballati o meno:
function Item({ name, isPacked }) { return <li className="item">{name}</li>; } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
Nota che alcuni componenti Item
hanno la loro prop isPacked
settata a true
invece che false
. Vuoi aggiungere un segno di spunta (✔) agli elementi imballati se isPacked={true}
.
Puoi scrivere questo come un’istruzione if
/else
in questo modo:
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;
Se la prop isPacked
è true
, questo codice ritorna un albero JSX differente. Con questo cambiamento, alcuni elementi ottengono un segno di spunta alla fine:
function Item({ name, isPacked }) { if (isPacked) { return <li className="item">{name} ✔</li>; } return <li className="item">{name}</li>; } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
Prova a modificare cosa viene ritornato in entrambi i casi e guarda come cambia il risultato!
Nota come stai creando una logica a diramazione con le istruzioni if
e return
di JavaScript. In React, il flusso di controllo (come le condizioni) è gestito da JavaScript.
Non restituire nulla condizionalmente con null
In alcune situazioni, non vorrai renderizzare nulla. Per esempio, diciamo che non vuoi mostrare gli elementi imballati. Un componente deve ritornare qualcosa. In questo caso, puoi ritornare null
:
if (isPacked) {
return null;
}
return <li className="item">{name}</li>;
Se isPacked
è true, il componente non renderizzerà nulla, ovvero null
. Altrimenti, ritornerà il JSX da renderizzare.
function Item({ name, isPacked }) { if (isPacked) { return null; } return <li className="item">{name}</li>; } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
Nella pratica, ritornare null
da un componente non è comune perché potrebbe sorprendere un developer che sta cercando di renderizzarlo. Più spesso, condizionerai l’inclusione o l’esclusione del componente nel JSX del componente genitore. Ecco qui come fare!
Includere JSX condizionalmente
Nell’esempio precedente, hai controllato quale albero JSX sarebbe stato ritornato dal componente (se presente!). Potresti aver già notato qualche duplicazione nell’output renderizzato:
<li className="item">{name} ✔</li>
è molto simile a
<li className="item">{name}</li>
Entrambi i rami condizionali ritornano <li className="item">...</li>
:
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;
Anche se questa duplicazione non è dannosa, potrebbe rendere il tuo codice più difficile da mantenere. Cosa succederebbe se volessi cambiare la className
? Dovresti farlo in due posti nel tuo codice! In una situazione del genere, potresti includere condizionalmente un po’ di JSX per rendere il tuo codice più DRY.
Operatore (ternario) condizionale (? :
)
JavaScript ha una sintassi compatta per scrivere un’espressione condizionale — l’operatore condizionale o “operatore ternario”.
Invece di questo:
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;
Puoi scrivere questo:
return (
<li className="item">
{isPacked ? name + ' ✔' : name}
</li>
);
Puoi leggerlo come “se isPacked
è true, allora (?
) renderizza name + ' ✔'
, altrimenti (:
) renderizza name
”.
Approfondimento
Se hai un background di programmazione orientata agli oggetti, potresti supporre che i due esempi sopra siano leggermente diversi perché uno di essi potrebbe creare due “istanze” diverse di <li>
. Ma gli elementi JSX non sono “istanze” perché non mantengono alcuno stato interno e non sono nodi del DOM reali. Sono descrizioni leggere, come i progetti. Quindi questi due esempi, infatti, sono completamente equivalenti. Preservare e Resettare lo Stato entra nel dettaglio su come funziona questo.
Ora immagina di voler racchiudere il testo dell’elemento completato in un altro tag HTML, come <del>
per barrarlo. Puoi aggiungere ancora più righe e parentesi cosí che sia più semplice annidare più JSX in ciascuno dei casi:
function Item({ name, isPacked }) { return ( <li className="item"> {isPacked ? ( <del> {name + ' ✔'} </del> ) : ( name )} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
Questo stile funziona bene per condizioni semplici, ma utilizzalo con moderazione. Se i tuoi componenti diventano disordinati con troppi markup condizionali nidificati, considera di estrarre i componenti figli per riordinare le cose. In React, il markup fa parte del tuo codice, quindi puoi usare strumenti come le variabili e le funzioni per ripulire le espressioni complesse.
Operatore logico AND (&&
)
Un’altra scorciatoia comune che incontrerai è l’operatore logico AND (&&
). All’interno dei componenti React, si presenta spesso quando si desidera renderizzare un po’ di JSX quando la condizione è vera, o altrimenti non si renderizza nulla. Con &&
, potresti renderizzare condizionalmente il segno di spunta solo se isPacked
è true
:
return (
<li className="item">
{name} {isPacked && '✔'}
</li>
);
Puoi leggere questo come “se isPacked
è true, allora (&&
) renderizza il segno di spunta, altrimenti, non renderizzare nulla”.
Eccolo in azione:
function Item({ name, isPacked }) { return ( <li className="item"> {name} {isPacked && '✔'} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
Una espressione JavaScript && restituisce il valore del suo lato destro (nel nostro caso, il segno di spunta) se il lato sinistro (la nostra condizione) è true
. Ma se la condizione è false
, l’intera espressione diventa false
. React considera false
come un “buco” nell’albero JSX, proprio come null
o undefined
e non renderizza nulla al suo posto.
Assegnare condizionalmente JSX ad una variabile
Quando introduci le scorciatoie nella scrittura di codice semplice, prova ad usare un’istruzione if
ed una variabile. Puoi riassegnare le variabili definite con let
, quindi inizia fornendo il contenuto predefinito che vuoi visualizzare, il nome:
let itemContent = name;
Utilizza un’istruzione if
per riassegnare un’espressione JSX ad itemContent
se isPacked
è true
:
if (isPacked) {
itemContent = name + " ✔";
}
Le parentesi graffe aprono una “finestra nel mondo JavaScript”. Inserisci la variabile con le parentesi graffe nell’albero JSX restituito, annidando l’espressione precedentemente calcolata all’interno del JSX:
<li className="item">
{itemContent}
</li>
Questo stile è più verboso, ma è anche più flessibile. Ecco come funziona:
function Item({ name, isPacked }) { let itemContent = name; if (isPacked) { itemContent = name + " ✔"; } return ( <li className="item"> {itemContent} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
Come prima, questo funziona non solo per il testo, ma anche per il JSX arbitrario:
function Item({ name, isPacked }) { let itemContent = name; if (isPacked) { itemContent = ( <del> {name + " ✔"} </del> ); } return ( <li className="item"> {itemContent} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
Se non hai familiarità con JavaScript, questa varietà di stili potrebbe sembrarti travolgente all’inizio. Tuttavia, impararli ti aiuterà a leggere e scrivere qualsiasi codice JavaScript - e non solo i componenti React! Scegli quello che preferisci per iniziare e poi consulta di nuovo questo riferimento se dimentichi come funzionano gli altri.
Riepilogo
- In React, controlli la logica di ramificazione con JavaScript.
- Puoi ritornare condizionalmente un’espressione JSX con un’istruzione
if
. - Puoi salvare condizionalmente un’espressione JSX in una variabile e quindi includerla in altri JSX utilizzando le parentesi graffe.
- Nella sintassi JSX,
{cond ? <A /> : <B />}
, significa second
ètrue
, renderizza<A />
, altrimenti<B />
. - Nella sintassi JSX,
{cond && <A />}
significa second
ètrue
, renderizza<A />
, altrimenti nulla. - Le scorciaotie sono comuni, ma non sei costretto ad utilizzarle se preferisci un semplice
if
.
Sfida 1 di 3: Mostra un’icona per gli oggetti incompleti con ? :
Usa l’operatore condizionale (cond ? a : b
) per renderizzare una ❌ se isPacked
non è true
.
function Item({ name, isPacked }) { return ( <li className="item"> {name} {isPacked && '✔'} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }