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
, 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 pada 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 ingin 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 Logika 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.
Menugaskan JSX secara Bersyarat ke sebuah Variabel
Saat pintasan menghalangi dalam penulisan kode biasa, coba gunakan pernyataan if
dan sebuah variabel. Anda dapat menetapkan ulang variabel yang telah ditentukan dengan menggunakan let
, jadi mulailah dengan menyediakan konten default yang ingin anda tampilkan, namanya:
let itemContent = name;
Gunakan pernyataan if
untuk menetapkan kembali ekspresi JSX ke itemContent
jika isPacked
adalah true
:
if (isPacked) {
itemContent = name + " ✔";
}
Kurung kurawal membuka “jendela ke JavaScript”. Menyematkan variabel dengan kurung kurawal di JSX tree yang dikembalikan, menyarangkan ekspresi yang sebelumnya dihitung di dalam JSX:
<li className="item">
{itemContent}
</li>
Gaya ini paling bertele-tele, tetapi juga yang paling fleksibel. Berikut adalah caranya:
function Item({ name, isPacked }) { let itemContent = name; if (isPacked) { itemContent = name + " ✔"; } return ( <li className="item"> {itemContent} </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> ); }
Seperti sebelumnya, cara ini bekerja tidak hanya pada teks, tetapi juga pada JSX yang sewenang-wenang:
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>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> ); }
Jika anda tidak terbiasa dengan JavaScript, variasi dari gaya ini mungkin tampak berlebihan pada awalnya. Namun, mempelajarinya akan membantu anda dalam membaca dan menulis kode JavaScript apa pun — dan bukan hanya komponen React! Pilih salah satu yang anda sukai sebagai permulaan, dan lihat kembali referensi ini jika anda lupa cara kerja yang lain.
Recap
- Di React, anda mengontrol logika percabangan dengan JavaScript.
- Anda dapat mengembalikan ekspresi JSX secara bersyarat menggunakan pernyataan
if
. - Anda dapat menyimpan beberapa JSX ke dalam sebuah variabel secara bersyarat dan kemudian memasukkannya ke dalam JSX yang lain dengan menggunakan kurung kurawal.
- Di JSX,
{cond ? <A /> : <B />}
berarti “jikacond
, render<A />
, jika tidak<B />
”. - Di JSX,
{cond && <A />}
berarti “jikacond
, render<A />
, jika tidak render apa pun”. - Pintasan itu umum, tapi anda tidak harus menggunakannya jika anda lebih menyukai pernyataan
if
.
Challenge 1 of 3: Tampilkan ikon untuk item yang tidak lengkap dengan menggunakan ? :
Gunakan operator bersyarat (cond ? a : b
) untuk me-render sebuah ❌ jika isPacked
bukan true
.
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> ); }