Uslovno renderovanje
Vaše komponente često trebaju prikazivati različite stvari u zavisnosti od različitih uslova. U React-u, možete uslovno renderovati JSX upotrebom JavaScript sintakse poput if
iskaza, &&
i ? :
operatora.
Naučićete:
- Kako da vratite različit JSX u zavisnosti od uslova
- Kako da uslovno uključite ili isključite deo JSX-a
- Uobičajene prečice za uslovnu sintaksu koje ćete sresti u React projektima
Uslovno vraćanje JSX-a
Napravimo PackingList
komponentu koja će renderovati par Item
-a, koji mogu, a ne moraju biti spakovani:
function Item({ name, isPacked }) { return <li className="item">{name}</li>; } export default function PackingList() { return ( <section> <h1>Lista za pakovanje od Sally Ride</h1> <ul> <Item isPacked={true} name="Svemirsko odelo" /> <Item isPacked={true} name="Kaciga sa zlatnim listom" /> <Item isPacked={false} name="Fotografija od Tam" /> </ul> </section> ); }
Primetite da neke Item
komponente imaju isPacked
prop setovan na true
umesto na false
. Želimo dodati kvačicu (✅) za spakovane proizvode ako je isPacked={true}
.
Ovo možete napisati kao if
/else
izraz poput:
if (isPacked) {
return <li className="item">{name} ✅</li>;
}
return <li className="item">{name}</li>;
Ako je isPacked
prop true
, ovaj kod vraća drugačije JSX stablo. Sa ovom promenom, neki proizvodi će imati kvačicu na kraju:
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>Lista za pakovanje od Sally Ride</h1> <ul> <Item isPacked={true} name="Svemirsko odelo" /> <Item isPacked={true} name="Kaciga sa zlatnim listom" /> <Item isPacked={false} name="Fotografija od Tam" /> </ul> </section> ); }
Promenite šta se vraća u oba slučaja i vidite kako se rezultat menja!
Uočite da se kreira logika grananja sa JavaScript-ovim if
i return
iskazima. U React-u, JavaScript je zadužen za kontrolni tok (npr. uslove).
Uslovno renderovanje ničega sa null
U nekim situacijama, nećete želeti da renderujete ništa. Na primer, uopšte ne želite da prikažete spakovane proizvode. Komponenta mora nešto da vrati. U ovom slučaju, možete vratiti null
:
if (isPacked) {
return null;
}
return <li className="item">{name}</li>;
Ako je isPacked
true, komponenta će vratiti ništa, null
. U suprotnom, vratiće JSX koji se renderuje.
function Item({ name, isPacked }) { if (isPacked) { return null; } return <li className="item">{name}</li>; } export default function PackingList() { return ( <section> <h1>Lista za pakovanje od Sally Ride</h1> <ul> <Item isPacked={true} name="Svemirsko odelo" /> <Item isPacked={true} name="Kaciga sa zlatnim listom" /> <Item isPacked={false} name="Fotografija od Tam" /> </ul> </section> ); }
U praksi, vraćanje null
iz komponente nije uobičajeno jer može iznenaditi developera koji pokuša da ga renderuje. Češće ćete uslovno uključiti ili isključiti komponentu u JSX-u roditeljske komponente. Evo kako to možete uraditi!
Uslovno uključivanje JSX-a
U prethodnom primeru, kontrolisali ste koje (možda nijedno!) JSX stablo će komponenta vratiti. Možda ste već uočili neko ponavljanje:
<li className="item">{name} ✅</li>
je veoma slično sa
<li className="item">{name}</li>
Obe uslovne grane vraćaju <li className="item">...</li>
:
if (isPacked) {
return <li className="item">{name} ✅</li>;
}
return <li className="item">{name}</li>;
Iako ovo ponavljanje nije štetno, ipak čini vaš kod težim za održavanje. Šta ako želite promeniti className
? Morali biste to učiniti na dva mesta u kodu! U ovakvim situacijama možete uslovno uključiti malo JSX-a da bi vaš kod bolje ispoštovao DRY.
Uslovni (ternarni) operator (? :
)
JavaScript sadrži kompaktnu sintaksu za pisanje uslovnih izraza — uslovni operator ili “ternarni operator”.
Umesto ovoga:
if (isPacked) {
return <li className="item">{name} ✅</li>;
}
return <li className="item">{name}</li>;
Možete napisati ovo:
return (
<li className="item">
{isPacked ? name + ' ✅' : name}
</li>
);
Ovo možete pročitati kao “ako je isPacked
true, onda (?
) renderuj name + ' ✅'
, u suprotnom (:
) renderuj name
”.
Deep Dive
Ako dolazite sa pozadinom objektno-orijentisanog programiranja, mogli biste pretpostaviti da se dva primera gore suptilno razlikuju zato što jedan od njih može kreirati dve “instance” <li>
. Ali, JSX elementi nisu “instance” zato što ne drže stanje i nisu pravi DOM čvorovi. Oni si laki opisi, nalik na nacrte. Tako da ova dva primera, u suštini, jesu potpuno jednaki. Očuvanje i resetovanje state-a detaljno opisuje kako ovo radi.
Hajde sad da obmotamo tekst spakovanog proizvoda u novi tag, <del>
, kako bi ga precrtali. Možete dodati i nove linije i zagrade kako bi bilo lakše da ugnjezdite dodatni JSX u oba slučaja:
function Item({ name, isPacked }) { return ( <li className="item"> {isPacked ? ( <del> {name + ' ✅'} </del> ) : ( name )} </li> ); } export default function PackingList() { return ( <section> <h1>Lista za pakovanje od Sally Ride</h1> <ul> <Item isPacked={true} name="Svemirsko odelo" /> <Item isPacked={true} name="Kaciga sa zlatnim listom" /> <Item isPacked={false} name="Fotografija od Tam" /> </ul> </section> ); }
Ovaj stil radi dobro za jednostavne uslove, ali koristite ga umereno. Ako vaše komponente postanu neuredne zbog previše ugnježdenih uslovnih markup-a, razmotrite izdvajanje dečjih komponenata kako biste ih poboljšali. U React-u, markup je deo vašeg koda, tako da možete koristiti alate poput promenljivih i funkcija da biste pojednostavili kompleksne izraze.
Logički “I” operator (&&
)
Još jedna uobičajena prečica koju ćete sresti je JavaScript-ov logički “I” (&&
) operator. Često se koristi unutar React komponenata kada želite da renderujete neki JSX kad je uslov true, ili da ne renderujete ništa u suprotnom. Sa &&
možete uslovno renderovati kvačicu samo kad je isPacked
true
:
return (
<li className="item">
{name} {isPacked && '✅'}
</li>
);
Ovo možete pročitati kao “ako je isPacked
, onda (&&
) renderuj kvačicu, u suprotnom ne renderuj ništa”.
Evo primera:
function Item({ name, isPacked }) { return ( <li className="item"> {name} {isPacked && '✅'} </li> ); } export default function PackingList() { return ( <section> <h1>Lista za pakovanje od Sally Ride</h1> <ul> <Item isPacked={true} name="Svemirsko odelo" /> <Item isPacked={true} name="Kaciga sa zlatnim listom" /> <Item isPacked={false} name="Fotografija od Tam" /> </ul> </section> ); }
JavaScript && izraz vraća vrednost svoje desne strane (u našem slučaju, kvačicu) ako je leva strana (naš uslov) true
. Ali, ako je uslov false
, ceo izraz postaje false
. React tumači false
kao “rupu” u JSX stablu, kao null
ili undefined
, i ne renderuje ništa na tom mestu.
Uslovna dodela JSX-a u promenljivu
Kada vas prečice sprečavaju da pišete običan kod, pokušajte da koristite if
iskaz i promenljivu. Možete dodeljivati vrednost promenljivama definisanim sa let
, pa počnite sa default sadržajem koji želite prikazati, imenom:
let itemContent = name;
Koristite if
iskaz da ponovo dodelite JSX izraz u itemContent
ako je isPacked
true
:
if (isPacked) {
itemContent = name + " ✅";
}
Vitičaste zagrade otvaraju “prozor u JavaScript”. Ugradite promenljivu sa vitičastim zagradama u povratno JSX stablo ugnježdavanjem prethodno izračunatog izraza unutar JSX-a:
<li className="item">
{itemContent}
</li>
Ovaj stil je najopširniji, ali je i najfleksibilniji. Evo primera:
function Item({ name, isPacked }) { let itemContent = name; if (isPacked) { itemContent = name + " ✅"; } return ( <li className="item"> {itemContent} </li> ); } export default function PackingList() { return ( <section> <h1>Lista za pakovanje od Sally Ride</h1> <ul> <Item isPacked={true} name="Svemirsko odelo" /> <Item isPacked={true} name="Kaciga sa zlatnim listom" /> <Item isPacked={false} name="Fotografija od Tam" /> </ul> </section> ); }
Kao i ranije, ovo ne radi samo za tekst, već i za proizvoljan JSX:
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>Lista za pakovanje od Sally Ride</h1> <ul> <Item isPacked={true} name="Svemirsko odelo" /> <Item isPacked={true} name="Kaciga sa zlatnim listom" /> <Item isPacked={false} name="Fotografija od Tam" /> </ul> </section> ); }
Ako niste upoznati sa JavaScript-om, ovolika raznovrsnost stilova može delovati preobimno na početku. Međutim, učenje tih stilova će vam pomoći da čitate i pišete bilo koji JavaScript kod — ne samo React komponente! Za početak izaberite jedan, a kasnije pogledajte ovaj članak ponovo ako zaboravite kako ostali funkcionišu.
Recap
- U React-u, logiku grananja kontrolišete pomoću JavaScript-a.
- Možete vratiti JSX izraz uslovno pomoću
if
iskaza. - Možete uslovno sačuvati neki JSX u promenljivu, a onda ga uključiti unutar drugog JSX-a pomoću vitičastih zagrada.
- U JSX-u,
{cond ? <A /> : <B />}
znači “ako jecond
, renderuj<A />
, u suprotnom<B />
”. - U JSX-u,
{cond && <A />}
znači “ako jecond
, renderuj<A />
, u suprotnom ništa”. - Prečice su česte, ali ne morate ih koristiti ako preferirate običan
if
.
Izazov 1 od 3: Prikazati ikonicu za proizvode koji nisu spakovani pomoću ? :
Koristite uslovni operator (cond ? a : b
) da renderujete ❌ ako isPacked
nije true
.
function Item({ name, isPacked }) { return ( <li className="item"> {name} {isPacked && '✅'} </li> ); } export default function PackingList() { return ( <section> <h1>Lista za pakovanje od Sally Ride</h1> <ul> <Item isPacked={true} name="Svemirsko odelo" /> <Item isPacked={true} name="Kaciga sa zlatnim listom" /> <Item isPacked={false} name="Fotografija od Tam" /> </ul> </section> ); }