Perenderan Kondisional
Komponen Anda akan seringkali perlu menampilkan hal yang berbeda tergantung pada kondisi yang berbeda. Di React, Anda dapat me-render JSX secara kondisional menggunakan sintaksis JavaScript seperti pernyataan if
, &&
, dan operator ? :
.
Anda akan mempelajari
- Cara mengembalikan JSX yang berbeda tergantung pada suatu kondisi
- Cara menyertakan atau mengecualikan bagian dari JSX secara kondisional
- Pintasan (shortcut) sintaksis kondisional yang umum yang akan Anda temui di basis kode (codebase) React
Mengembalikan JSX secara kondisional
Katakanlah Anda memiliki komponen PackingList
yang me-render beberapa Item
, yang dapat ditandai sebagai dikemas atau tidak:
function Item({ name, isPacked }) { return <li className="item">{name}</li>; } export default function PackingList() { return ( <section> <h1>Daftar Pengemasan Sally Ride</h1> <ul> <Item isPacked={true} name="Pakaian luar angkasa" /> <Item isPacked={true} name="Helm berwarna emas" /> <Item isPacked={false} name="Foto Tam" /> </ul> </section> ); }
Perhatikan bahwa beberapa komponen Item
memiliki prop isPacked
yang disetel ke true
, bukan false
. Anda ingin menambahkan tanda centang (✔) pada item yang sudah dikemas jika isPacked={true}
.
Anda dapat menuliskannya sebagai pernyataan if
/else
seperti ini:
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;
Jika prop isPacked
bernilai true
, kode ini mengembalikan pohon JSX yang berbeda. Dengan perubahan ini, beberapa item akan mendapatkan 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>Daftar Pengemasan Sally Ride</h1> <ul> <Item isPacked={true} name="Pakaian luar angkasa" /> <Item isPacked={true} name="Helm berwarna emas" /> <Item isPacked={false} name="Foto Tam" /> </ul> </section> ); }
Coba edit apa yang akan dikembalikan dalam kedua kasus tersebut, dan lihat bagaimana hasilnya berubah!
Perhatikan bagaimana Anda membuat logika bercabang dengan pernyataan if
dan return
JavaScript. Dalam React, aliran kontrol (seperti kondisi) ditangani oleh JavaScript.
Tidak mengembalikan elemen apa pun secara kondisional dengan null
Dalam beberapa situasi, Anda tidak ingin me-render apa pun. Sebagai contoh, katakanlah Anda tidak ingin menampilkan item yang dikemas sama sekali. Sebuah komponen harus mengembalikan sesuatu. Dalam kasus ini, Anda dapat mengembalikan null
:
if (isPacked) {
return null;
}
return <li className="item">{name}</li>;
Jika nilai isPacked
adalah true, komponen tidak akan mengembalikan apa-apa, null
. Jika tidak, komponen ini 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>Daftar Pengemasan Sally Ride</h1> <ul> <Item isPacked={true} name="Pakaian luar angkasa" /> <Item isPacked={true} name="Helm berwarna emas" /> <Item isPacked={false} name="Foto Tam" /> </ul> </section> ); }
Dalam praktiknya, mengembalikan null
dari sebuah komponen tidaklah umum karena dapat mengejutkan pengembang yang mencoba me-render-nya. Lebih sering, Anda akan menyertakan atau mengecualikan komponen secara kondisional dalam JSX komponen induk. Inilah cara untuk melakukannya!
Menyertakan JSX secara kondisional
Pada contoh sebelumnya, Anda mengontrol pohon JSX mana (jika ada!) yang akan dikembalikan oleh komponen. Anda mungkin telah melihat beberapa duplikasi pada keluaran render:
<li className="item">{name} ✔</li>
is very similar to
<li className="item">{name}</li>
Kedua cabang kondisional mengembalikan <li className="item">...</li>
:
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;
Meskipun duplikasi ini tidak berbahaya, namun dapat membuat kode Anda menjadi lebih sulit untuk dipelihara. Bagaimana jika Anda ingin mengubah className
? Anda harus melakukannya di dua tempat dalam kode Anda! Dalam situasi seperti ini, Anda dapat menyertakan sedikit JSX secara kondisional untuk membuat kode Anda lebih [DRY.] (https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)
Operator kondisional (ternary) (? :
)
JavaScript memiliki sintaks yang ringkas untuk menulis ekspresi bersyarat — the operator kondisional atau “operator ternary”.
Daripada ini:
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;
Anda bisa menulis ini:
return (
<li className="item">
{isPacked ? name + ' ✔' : name}
</li>
);
Anda dapat membacanya sebagai “jika nilai isPacked
adalah true, maka (?
) render name + ' ✔'
, jika tidak (:
) render name
”.
Pendalaman
Jika Anda berasal dari latar belakang pemrograman berorientasi objek, Anda mungkin berasumsi bahwa kedua contoh di atas sangat berbeda karena salah satu contoh tersebut dapat membuat dua “instance” yang berbeda dari <li>
. Tetapi elemen JSX bukanlah “instance” karena mereka tidak memiliki state internal dan bukan merupakan simpul DOM yang sebenarnya. Mereka adalah deskripsi ringan, seperti cetak biru. Jadi, kedua contoh ini, pada kenyataannya, sebenarnya sepenuhnya setara. Mempertahankan dan Mengatur Ulang State menjelaskan secara detail tentang cara kerjanya.
Sekarang katakanlah Anda ingin membungkus teks item yang sudah selesai ke dalam tag HTML lain, seperti <del>
untuk memcoretnya. Anda dapat menambahkan lebih banyak lagi baris baru dan tanda kurung sehingga lebih mudah untuk menyarangkan lebih banyak JSX dalam setiap kasus:
function Item({ name, isPacked }) { return ( <li className="item"> {isPacked ? ( <del> {name + ' ✔'} </del> ) : ( name )} </li> ); } export default function PackingList() { return ( <section> <h1>Daftar Pengemasan Sally Ride</h1> <ul> <Item isPacked={true} name="Pakaian luar angkasa" /> <Item isPacked={true} name="Helm berwarna emas" /> <Item isPacked={false} name="Foto Tam" /> </ul> </section> ); }
Model seperti ini bekerja dengan baik untuk kondisi sederhana, tetapi gunakan secukupnya. Jika komponen Anda menjadi berantakan dengan terlalu banyak markup kondisional bersarang, pertimbangkan untuk mengekstrak komponen turunan untuk membereskannya. Di React, markup adalah bagian dari kode Anda, sehingga Anda dapat menggunakan alat bantu seperti variabel dan fungsi untuk merapikan ekspresi yang kompleks.
Operator logis AND (&&
)
Pintasan umum lainnya yang akan Anda temui adalah operator logis AND (&&
) JavaScript. Di dalam komponen React, hal ini sering muncul ketika Anda ingin me-render beberapa JSX ketika kondisinya true, atau tidak me-render apapuin jika sebaliknya. Dengan &&
, Anda dapat me-render tanda centang secara kondisional hanya jika isPacked
bernilai true
:
return (
<li className="item">
{name} {isPacked && '✔'}
</li>
);
Anda dapat membacanya sebagai “jika isPacked
, maka (&&
) render tanda centang, sebaliknya, jangan render apa pun”.
Here it is in action:
function Item({ name, isPacked }) { return ( <li className="item"> {name} {isPacked && '✔'} </li> ); } export default function PackingList() { return ( <section> <h1>Daftar Pengemasan Sally Ride</h1> <ul> <Item isPacked={true} name="Pakaian luar angkasa" /> <Item isPacked={true} name="Helm berwarna emas" /> <Item isPacked={false} name="Foto Tam" /> </ul> </section> ); }
Ekspresi && JavaScript mengembalikan nilai sisi kanannya (dalam kasus kita, tanda centang) jika sisi kiri (kondisi kita) adalah true
. Tetapi jika kondisinya adalah false
, seluruh ekspresi menjadi false
. React menganggap false
sebagai sebuah “lubang” pada pohon JSX, seperti halnya null
atau undefined
, dan tidak me-render apa pun sebagai gantinya.
Menetapkan JSX secara kondisional ke sebuah variabel
Ketika pintasan menghalangi penulisan kode biasa, cobalah menggunakan pernyataan if
dan variabel. Anda dapat menetapkan ulang variabel yang didefinisikan dengan let
, jadi mulailah dengan memberikan konten default yang ingin Anda tampilkan, yaitu nama:
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 dalam JavaScript”. Tempelkan variabel dengan kurung kurawal pada pohon JSX yang dikembalikan, menyarangkan ekspresi yang telah dikalkulasi sebelumnya di dalam JSX:
<li className="item">
{itemContent}
</li>
Model ini adalah model yang paling bertele-tele, tetapi juga paling fleksibel. Ini contohnya:
function Item({ name, isPacked }) { let itemContent = name; if (isPacked) { itemContent = name + " ✔"; } return ( <li className="item"> {itemContent} </li> ); } export default function PackingList() { return ( <section> <h1>Daftar Pengemasan Sally Ride</h1> <ul> <Item isPacked={true} name="Pakaian luar angkasa" /> <Item isPacked={true} name="Helm berwarna emas" /> <Item isPacked={false} name="Foto Tam" /> </ul> </section> ); }
Seperti sebelumnya, ini tidak hanya berfungsi untuk teks, tetapi juga untuk JSX sembarang:
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>Daftar Pengemasan Sally Ride</h1> <ul> <Item isPacked={true} name="Pakaian luar angkasa" /> <Item isPacked={true} name="Helm berwarna emas" /> <Item isPacked={false} name="Foto Tam" /> </ul> </section> ); }
Jika Anda tidak terbiasa dengan JavaScript, variasi gaya ini mungkin tampak membingungkan pada awalnya. Namun, dengan mempelajarinya akan membantu Anda membaca dan menulis kode JavaScript apa pun — dan bukan hanya komponen React! Pilih salah satu yang Anda sukai sebagai permulaan, lalu lihat referensi ini lagi jika Anda lupa cara kerja yang lain.
Rekap
- Di React, Anda dapat mengontrol logika percabangan dengan JavaScript.
- Anda dapat mengembalikan ekspresi JSX secara kondisional dengan pernyataan
if
. - Anda dapat menyimpan beberapa JSX secara kondisional ke sebuah variabel dan kemudian menyertakannya di dalam JSX lain dengan menggunakan kurung kurawal.
- Dalam JSX,
{cond ? <A /> : <B />}
berarti “jikacond
, render<A />
, sebaliknya<B />
”. - Dalam JSX,
{cond && <A />}
berarti “jikacond
, render<A />
, sebaliknya jangan render apa pun”. - Pintasan ini umum digunakan, tetapi Anda tidak perlu menggunakannya jika Anda lebih suka
if
biasa.
Tantangan 1 dari 3: Menampilkan ikon untuk item yang tidak lengkap dengan ? :
Gunakan operator kondisional (cond ? a : b
) untuk me-render ❌ jika isPacked
tidak true
.
function Item({ name, isPacked }) { return ( <li className="item"> {name} {isPacked && '✔'} </li> ); } export default function PackingList() { return ( <section> <h1>Daftar Pengemasan Sally Ride</h1> <ul> <Item isPacked={true} name="Pakaian luar angkasa" /> <Item isPacked={true} name="Helm berwarna emas" /> <Item isPacked={false} name="Foto Tam" /> </ul> </section> ); }