Renderowanie warunkowe
Twoje komponenty zazwyczaj będą wyświetlały różne informacje w zależności od różnych warunków. W Reakcie możesz renderować warunkowo JSX używając składni javascriptowej, takiej jak warunek if
czy operatory &&
i ? :
.
W tej sekcji dowiesz się
- Jak zwrócić różny kod JSX w zależności od warunku
- Jak warunkowo wyświetlić lub wykluczyć część JSX-a
- Powszechne skróty składni warunkowej, które napotkasz w bazach kodu reactowego
Warunkowe zwracanie JSX-a
Załóżmy, że masz komponent PackingList
renderujący kilka przedmiotów Item
, które mogą być oznaczone jako spakowane isPacked={true}
lub niespakowane isPacked={false}
:
function Item({ name, isPacked }) { return <li className="item">{name}</li>; } export default function PackingList() { return ( <section> <h1>Lista rzeczy do spakowania Sally Ride</h1> <ul> <Item isPacked={true} name="Skafander kosmiczny" /> <Item isPacked={true} name="Hełm ze złotym liściem" /> <Item isPacked={false} name="Zdjęcie Tam" /> </ul> </section> ); }
Zauważ, że dla niektórych komponentów Item
właściwość isPacked
ustawiono na true
zamiast false
. Chcielibyśmy, żeby przy spakowanych przedmiotach, które mają ustawione isPacked={true}
, wyświetlał się “ptaszek” (✔).
Możesz to zapisać za pomocą warunku if
/else
w ten sposób:
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;
Jeśli właściwość isPacked
jest ustawiona na true
, ten kod zwróci odmienne drzewo JSX. Wraz z tą zmianą, niektóre z elementów zostaną wyrenderowane wraz z znacznikiem ✔.
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 rzeczy do spakowania Sally Ride</h1> <ul> <Item isPacked={true} name="Skafander kosmiczny" /> <Item isPacked={true} name="Hełm ze złotym liściem" /> <Item isPacked={false} name="Zdjęcie Tam" /> </ul> </section> ); }
Spróbuj edytować kod i sprawdź, co zostanie zwrócone w obu przypadkach oraz jak zmieni się wynik!
Zwróć uwagę, jak tworzysz logikę rozgałęzień za pomocą javascriptowych instrukcji if
oraz return
. W Reakcie kontrola przepływu (taka jak warunki) jest obsługiwana przez JavaScript.
Warunkowe zwracanie niczego z użyciem null
W pewnych sytuacjach nie będziesz chcieć niczego renderować. Dla przykładu, załóżmy, że w ogóle nie chcesz wyświetlać spakowanych przedmiotów. Komponent jednak musi coś zwrócić. W takim przypadku możesz zwrócić null
.
if (isPacked) {
return null;
}
return <li className="item">{name}</li>;
Jeśli isPacked
ma wartość true
, komponent nic nie zwróci - null
. W przeciwnym razie zwróci JSX do wyrenderowania.
function Item({ name, isPacked }) { if (isPacked) { return null; } return <li className="item">{name}</li>; } export default function PackingList() { return ( <section> <h1>Lista rzeczy do spakowania Sally Ride</h1> <ul> <Item isPacked={true} name="Skafander kosmiczny" /> <Item isPacked={true} name="Hełm ze złotym liściem" /> <Item isPacked={false} name="Zdjęcie Tam" /> </ul> </section> ); }
W praktyce, zwykle komponenty nie zwracają null
, ponieważ może to okazać się zaskakujące dla dewelopera, który próbuje wyrenderować dany komponent. Częściej zdarza się, że warunkowo wyświetlamy bądź nie komponent w kodzie JSX-owym rodzica. Oto jak to zrobić!
Warunkowe wyświetlanie JSX-a
W poprzednim przykładzie nasz kod decydował, które (jeśli którekolwiek) drzewo JSX-owe zostanie zwrócone przez komponent. Być może widzisz pewne powtórzenia w wyniku renderowania:
<li className="item">{name} ✔</li>
jest bardzo podobne do:
<li className="item">{name}</li>
Oba warunkowe rozgałęzienia zwracają <li className="item">...</li>
:
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;
W tym przypadku powielenia nie są szkodliwe, jednak mogą one utrudniać utrzymanie kodu. Co w sytuacji, gdybyśmy chcieli zmienić className
? Wówczas musielibyśmy to zrobić w dwóch miejscach w kodzie. W takich sytuacjach można warunkowo dołączyć JSX, aby kod był bardziej DRY.
Operator warunkowy (? :
)
JavaScript posiada zwartą składnię do tworzenia wyrażenia warunkowego — operator warunkowy, zwany także “operatorem ternarnym” (trójargumentowym).
Zamiast poniższego kodu:
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;
Możesz napisać w ten sposób:
return (
<li className="item">
{isPacked ? name + ' ✔' : name}
</li>
);
Możesz to wyrażenie przeczytać jako: “jeśli isPacked
ma wartość true
, wtedy (?
) wyrenderuj name + ' ✔'
, w przeciwnym razie (:
) wyrenderuj name
.“)
Dla dociekliwych
Jeśli wywodzisz się z programowania obiektowego, możesz założyć, że dwa powyższe przykłady są nieco inne, ponieważ jeden z nich może tworzyć dwie różne “instancje” <li>
. Jednak elementy JSX nie są “instancjami”, ponieważ nie przechowują żadnego stanu wewnętrznego oraz nie są prawdziwymi węzłami DOM. Tak więc te dwa przykłady są w pełni równoważne. Rozdział pt. Zachowywanie i resetowanie stanu zawiera szczegółowe informacje o tym, jak to działa.
Załóżmy, że mamy zadanie umieścić tekst ukończonego elementu w innym znaczniku HTML, na przykład <del>
, aby uzyskać efekt przekreślenia. Możesz dodać więcej nowych linii i nawiasów, aby było łatwiej zagnieżdżać więcej JSX w każdym z przypadków:
function Item({ name, isPacked }) { return ( <li className="item"> {isPacked ? ( <del> {name + ' ✔'} </del> ) : ( name )} </li> ); } export default function PackingList() { return ( <section> <h1>Lista rzeczy do spakowania Sally Ride</h1> <ul> <Item isPacked={true} name="Skafander kosmiczny" /> <Item isPacked={true} name="Hełm ze złotym liściem" /> <Item isPacked={false} name="Zdjęcie Tam" /> </ul> </section> ); }
Ten sposób sprawdza się przy prostych warunkach, używaj go jednak z umiarem. Jeśli twój komponent robi się nieczytelny, ponieważ posiada zbyt dużą liczbę warunków, rozważ wyodrębnienie komponentów podrzędnych, aby go uporządkować. W Reakcie znaczniki są częścią twojego kodu, więc możesz używać narzędzi takich jak zmienne oraz funkcje do porządkowania złożonych wyrażeń.
Operator logiczny AND (&&
)
Kolejnym powszechnie stosowanym skrótem, z którym możesz się zetknąć, jest javascriptowy operator logiczny AND (&&
). Wewnątrz komponentów reactowych często wykorzystujemy go, gdy chcemy wyrenderować JSX przy spełnieniu warunku lub gdy nie chcemy nic renderować przy niespełnionym warunku. Przy pomocy operatora &&
możesz warunkowo wyrenderować “ptaszek” (✔) tylko wtedy, kiedy właściwość isPacked
jest ustawiona na true
.
return (
<li className="item">
{name} {isPacked && '✔'}
</li>
);
Możesz to wyrażenie przeczytać jako: “jeśli isPacked
, wtedy (&&
) wyrenderuj “ptaszek” ✔; w przeciwnym razie nic nie renderuj.”
Poniżej przedstawiono przykład:
function Item({ name, isPacked }) { return ( <li className="item"> {name} {isPacked && '✔'} </li> ); } export default function PackingList() { return ( <section> <h1>Lista rzeczy do spakowania Sally Ride</h1> <ul> <Item isPacked={true} name="Skafander kosmiczny" /> <Item isPacked={true} name="Hełm ze złotym liściem" /> <Item isPacked={false} name="Zdjęcie Tam" /> </ul> </section> ); }
Wyrażenie && w JavaScripcie zwraca wartość z prawej strony operatora (w naszym przypadku “ptaszek” ✔), jeśli po lewej stronie warunek został spełniony (ma wartość true
). Jeśli jednak warunek ma wartość false
, całe wyrażenie staje się false
i nie zostaje spełnione. React traktuje false
jako “dziurę” w drzewie JSX, podobnie jak null
czy undefined
i nie renderuje niczego w tym miejscu.
Warunkowe przypisywanie JSX-a do zmiennej
Jeśli skróty przeszkadzają w pisaniu zwykłego kodu, spróbuj użyć warunku if
oraz zmiennej. Możesz ponownie przypisać wartości do zmiennej, zdefiniowanej za pomocą let
, zacznij więc od podania domyślnej wartości, którą chcesz wyświetlić:
let itemContent = name;
Użyj warunku if
, aby przypisać ponownie wyrażenie JSX-owe do itemContent
, jeśli isPacked
posiada wartość true
:
if (isPacked) {
itemContent = name + " ✔";
}
Używanie nawiasów klamrowych otwiera “okno na świat JavaScriptu”. Umieść zmienną wewnątrz nawiasów klamrowych w zwróconym drzewie JSX, zagnieżdżając uprzednio przeliczone wyrażenie wewnątrz JSX:
<li className="item">
{itemContent}
</li>
Ten sposób jest najbardziej rozwlekły, jednocześnie jednak najbardziej elastyczny. Poniżej przedstawiono przykład:
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 rzeczy do spakowania Sally Ride</h1> <ul> <Item isPacked={true} name="Skafander kosmiczny" /> <Item isPacked={true} name="Hełm ze złotym liściem" /> <Item isPacked={false} name="Zdjęcie Tam" /> </ul> </section> ); }
Tak jak poprzednio, ten sposób działa nie tylko dla tekstu, ale także dla dowolnego kodu 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 rzeczy do spakowania Sally Ride</h1> <ul> <Item isPacked={true} name="Skafander kosmiczny" /> <Item isPacked={true} name="Hełm ze złotym liściem" /> <Item isPacked={false} name="Zdjęcie Tam" /> </ul> </section> ); }
Jeśli znasz dobrze JavaScriptu, ta różnorodność sposobów może początkowo wydawać się przytłaczająca. Jednak ich nauka pomoże ci czytać i pisać dowolny kod javascriptowy — nie tylko komponenty reactowe! Na początku wybierz jeden preferowany sposób, a następnie zapoznaj się ponownie z tymi notatkami, jeśli zapomnisz zasady działania pozostałych.
Powtórka
- W Reakcie kontrolujesz logikę rozgałęzień za pomocą JavaScriptu.
- Możesz zwrócić wyrażenie JSX-owe warunkowo, używając do tego instrukcji
if
. - Możesz warunkowo zapisać część kodu JSX w zmiennej, a następnie dołączyć go do innego kodu JSX, używając nawiasów klamrowych.
- W JSX
{warunek ? <A /> : <B />}
oznacza: “jeśliwarunek
jest prawdziwy, wyrenderuj<A />
, w przeciwnym razie wyrenderuj<B />
”. - W JSX
{warunek && <A />}
oznacza: “jeśliwarunek
jest prawdziwy, wyrenderuj<A />
, w przeciwnym razie nic nie renderuj”. - Skrótowy zapis jest dość powszechny, ale nie musisz go używać, jeśli wolisz zwykłe
if
.
Wyzwanie 1 z 3: Wyświetl znacznik dla niespakowanych przedmiotów za pomocą ? :
Użyj operatora warunkowego (warunek ? a : b
), aby wyświetlić ❌, jeśli isPacked
nie ma wartości true
.
function Item({ name, isPacked }) { return ( <li className="item"> {name} {isPacked && '✔'} </li> ); } export default function PackingList() { return ( <section> <h1>Lista rzeczy do spakowania Sally Ride</h1> <ul> <Item isPacked={true} name="Skafander kosmiczny" /> <Item isPacked={true} name="Hełm ze złotym liściem" /> <Item isPacked={false} name="Zdjęcie Tam" /> </ul> </section> ); }