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śliwarunekjest prawdziwy, wyrenderuj<A />, w przeciwnym razie wyrenderuj<B />”. - W JSX
{warunek && <A />}oznacza: “jeśliwarunekjest 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> ); }