Conditional Rendering
Komponen anda sering diperlukan untuk menampilkan hal yang berbeda tergantung dari beberapa kondisi yang berbeda. Di React, anda dapat melakukan render JSX secara bersyarat menggunakan sintaks JavaScript seperti pernyataan if
, &&
, dan ? :
operator.
You will learn
- Cara mengembalikan JSX yang berbeda tergantung dari suatu kondisi
- Bagaimana cara memasukkan atau mengecualikan sepotong JSX secara bersyarat
- Pintasan sintaks bersyarat umum yang akan anda temukan di basis kode React
Mengembalikan JSX secara Bersyarat
Katakanlah anda memiliki komponen PackingList
yang melakukan render pada beberapa Item
s, yang dapat ditandai secara dikemas atau tidak:
function Item({ name, isPacked }) { return <li className="item">{name}</li>; } export default function PackingList() { return ( <section> <h1>Andrian 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> ); }
Perhatikan bahwa beberapa komponen Item
memiliki properti isPacked
yang disetel menjadi true
daripada false
. Anda ingin menambahkan tanda centang (✔) ke Item
yang dikemas jika isPacked={true}
.
Anda dapat menulis ini sebagai pernyataan if
/else
seperti ini:
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;
Jika properti isPacked
adalah true
, kode ini mengembalikan JSX tree yang berbeda. Dengan perubahan ini, beberapa item
mendapat tanda centang di bagian akhir:
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>Andrian 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> ); }
Coba melakukan edit apa yang dikembalikan dalam kedua kasus tersebut, dan lihat bagaimana hasilnya berubah!
Perhatikan bagaimana anda membuat logika bercabang dengan pernyataan if
dan return
menggunakan JavaScript. Di React, alur kontrol (seperti kondisi) ditangani oleh JavaScript.
Tidak mengembalikan apa pun secara bersyarat dengan null
Dalam kondisi tertentu, anda tidak ingin me-render apa pun. Sebagai Contoh, katakan anda tidak mau menampilkan item
yang dikemas. Sebuah komponen harus mengembalikan sesuatu. Dalam kasus ini, anda dapat mengambalikan null
:
if (isPacked) {
return null;
}
return <li className="item">{name}</li>;
Jika isPacked
adalah true
, komponen tidak akan mengembalikan apa pun, null
. Jika tidak, itu akan mengembalikan JSX untuk di-render.
function Item({ name, isPacked }) { if (isPacked) { return null; } return <li className="item">{name}</li>; } export default function PackingList() { return ( <section> <h1>Andrian 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> ); }
Dalam praktiknya, mengembalikan null
dari sebuah komponen itu tidak umum karena dapat mengejutkan developer yang mencoba untuk me-render-nya. Lebih sering, anda akan menyertakan atau mengecualikan komponen secara bersyarat di komponen induk JSX. Berikut adalah cara untuk melakukannya!
Secara Bersyarat memasukkan JSX
Pada contoh sebelumnya, anda mengontrol JSX tree mana (if any!) yang akan dikembalikan oleh komponen. Anda mungkin telah memperhatikan beberapa duplikasi dalam hasil render:
<li className="item">{name} ✔</li>
mirip dengan
<li className="item">{name}</li>
Kedua branches bersyarat tersebut mengembalikan <li className="item">...</li>
:
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;
Meskipun duplikasi ini tidak berbahaya, ini dapat membuka kode anda lebih susah untuk di-maintain. Bagaimana jika anda ingi mengganti className
nya? Anda harus melakukannya di dua tempat dalam kode anda! Dalam situasi seperti itu, anda dapat menyertakan sedikit JSX secara bersyarat untuk membuat kode anda lebih DRY.
Operator (? :
) bersyarat (ternary)
JavaScript memiliki syntax yang ringkas untuk menulis ekspresi bersyarat — operator bersyarat atau sering disebut sebagai “ternary operator”.
Daripada ini:
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;
Anda dapat menulis ini:
return (
<li className="item">
{isPacked ? name + ' ✔' : name}
</li>
);
anda dapat membacanya sebagai “jika isPacked
adalah true
, maka (?
) render name + ' ✔'
, jika tidak (:
) render name
”.
Deep Dive
Jika anda berasal dari latar belakang pemrograman berorientasi objek, anda mungkin berasumsi bahwa kedua contoh tersebut sedikit berbeda karena salah satunya dapat membuat dua jenis “instansi” <li>
berbeda. Tetapi elemen JSX bukan “instansi” karena mereka tidak memiliki state internal dan bukan node DOM yang sebenarnya. Itu deskripsi ringan, seperti cetak biru. Jadi kedua contoh ini, sebenarnya, adalah benar-benar sama. Preserving and Resetting State menjelaskan lebih detil bagaimana hal ini bekerja.
Sekarang katakanlah anda ingin membungkus teks item
yang sudah selesai ke dalam tag HTML lain, seperti <del>
untuk mencoretnya. Anda bahkan dapat menambahkan lebih banyak baris baru dan tanda kurung sehingga lebih mudah untuk menyarankan lebih banyak JSX di setiap kasus:
function Item({ name, isPacked }) { return ( <li className="item"> {isPacked ? ( <del> {name + ' ✔'} </del> ) : ( name )} </li> ); } export default function PackingList() { return ( <section> <h1>Andrian 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> ); }
Gaya ini bekerja dengan baik untuk kondisi yang sederhana, tetapi gunakan dengan secukupnya. Jika komponen anda berantakan dengan terlalu banyak markup bersyarat bersarang (nested conditional markup), pertimbangkan untuk mengekstrak komponen turunan untuk membersihkan semuanya. Di React, markup adalah bagian dari kode anda, sehingga anda dapat menggunakan alat seperti variabel (variables
) dan fungsi (functions
) untuk merapikan ekspresi yang kompleks.
Operator Logis AND (&&
)
Pintasan umum lainnya yang akan anda temui adalah JavaScript logical AND (&&
) operator. Di Dalam komponen React, hal tersebut sering muncul ketika anda ingin me-render beberapa JSX apabila memiliki kondisi true
, atau tidak me-render sebaliknya. Dengan &&
, anda dapat me-render tanda centang secara bersyarat hanya jika isPacked
adalah true
:
return (
<li className="item">
{name} {isPacked && '✔'}
</li>
);
Anda dapat membaca ini sebagai “jika isPacked
, maka (&&
) render tanda centang, jika tidak, tidak render apa pun”.
Seperti berikut:
function Item({ name, isPacked }) { return ( <li className="item"> {name} {isPacked && '✔'} </li> ); } export default function PackingList() { return ( <section> <h1>Andrian 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> ); }
Ekspresi && JavaScript mengembalikan nilai sisi kanannya (dalam kasus ini, tanda centang) jika sisi kirinya (kondisi kita) adalah true
. Tetapi jika kondisinya adalah false
, seluruh ekspresi menjadi false
. React menganggap false
sebagai sebuah “lubang” pada JSX tree, sama seperti null
atau undefined
, dan tidak me-render apa pun di tempatnya.
Conditionally assigning JSX to a variable
When the shortcuts get in the way of writing plain code, try using an if
statement and a variable. You can reassign variables defined with let
, so start by providing the default content you want to display, the name:
let itemContent = name;
Use an if
statement to reassign a JSX expression to itemContent
if isPacked
is true
:
if (isPacked) {
itemContent = name + " ✔";
}
Curly braces open the “window into JavaScript”. Embed the variable with curly braces in the returned JSX tree, nesting the previously calculated expression inside of JSX:
<li className="item">
{itemContent}
</li>
This style is the most verbose, but it’s also the most flexible. Here it is in action:
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> ); }
Like before, this works not only for text, but for arbitrary JSX too:
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> ); }
If you’re not familiar with JavaScript, this variety of styles might seem overwhelming at first. However, learning them will help you read and write any JavaScript code — and not just React components! Pick the one you prefer for a start, and then consult this reference again if you forget how the other ones work.
Recap
- In React, you control branching logic with JavaScript.
- You can return a JSX expression conditionally with an
if
statement. - You can conditionally save some JSX to a variable and then include it inside other JSX by using the curly braces.
- In JSX,
{cond ? <A /> : <B />}
means “ifcond
, render<A />
, otherwise<B />
”. - In JSX,
{cond && <A />}
means “ifcond
, render<A />
, otherwise nothing”. - The shortcuts are common, but you don’t have to use them if you prefer plain
if
.
Challenge 1 of 3: Show an icon for incomplete items with ? :
Use the conditional operator (cond ? a : b
) to render a ❌ if isPacked
isn’t 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> ); }