Conditional Rendering Solid — SolidJS

Solid menyediakan komponen Show dan Switch/Match untuk conditional rendering. Show import { Show } from "solid-js" function App() { const [loggedIn…

Conditional rendering artinya memilih apa yang tampil berdasarkan sebuah kondisi. Solid punya dua komponen bawaan untuk itu: <Show> untuk "kalau begini tampilkan ini, kalau gak tampilkan itu", dan <Switch> berisi beberapa <Match> untuk pilihan yang lebih dari dua. Bayangin rak Laskar Pelangi di Toko Buku Kak Nadia. Selama stoknya ada, di rak itu ada tombol Beli 1. Begitu habis, tombolnya diganti papan Stok habis. Untuk label status, Kak Nadia memeriksa aturannya dari atas ke bawah ("habis?", "sisa sedikit?", "tersedia?") dan memasang papan dari aturan pertama yang cocok.

🧪 Tebakan cepat: label stok ditulis dengan <Switch>, tapi urutannya <Match when={stok() < 3}>Sisa sedikit</Match> dulu, baru <Match when={stok() === 0}>Habis</Match>. Saat stok 0, labelnya Habis atau Sisa sedikit? Jawabannya ada di bagian "Switch dan Match: cabang pertama yang benar".

Show: when dan fallback

import { createSignal, Show } from "solid-js"

function App() {
  const [loggedIn, setLoggedIn] = createSignal(false)

  return (
    <div>
      <Show when={loggedIn()} fallback={<p>Silakan login</p>}>
        <p>Selamat datang!</p>
      </Show>
      <button onClick={() => setLoggedIn(v => !v)}>
        {loggedIn() ? "Logout" : "Login"}
      </button>
    </div>
  )
}
Kejadian loggedIn() Yang tampil
Halaman dibuka false <p>Silakan login</p>
Klik sekali true <p>Selamat datang!</p>
Klik lagi false <p>Silakan login</p>

Tombol Beli atau "Stok habis"

Kartu Laskar Pelangi dengan stok 4. Tombol belinya dibuat oleh komponen kecil yang mencetak ke console tiap kali dia jalan:

import { createSignal, Show, Switch, Match } from "solid-js"

function TombolBeli(props) {
  console.log("TombolBeli jalan")
  return <button onClick={props.onBeli}>Beli 1</button>
}

function App() {
  const [stok, setStok] = createSignal(4)

  return (
    <div class="kartu">
      <h2>Laskar Pelangi</h2>
      <p>Stok: {stok()}</p>
      <Switch>
        <Match when={stok() === 0}><span>Habis</span></Match>
        <Match when={stok() < 3}><span>Sisa sedikit</span></Match>
        <Match when={stok() >= 3}><span>Tersedia</span></Match>
      </Switch>
      <Show when={stok() > 0} fallback={<p>Stok habis</p>}>
        <TombolBeli onBeli={() => setStok(s => s - 1)} />
      </Show>
      <button onClick={() => setStok(s => s + 3)}>Restok +3</button>
    </div>
  )
}
Kejadian stok() Label Bagian Show Console
Halaman dibuka 4 Tersedia tombol Beli 1 TombolBeli jalan
Klik Beli 1 3 Tersedia tombol yang sama
Klik Beli 1 2 Sisa sedikit tombol yang sama
Klik Beli 1 dua kali 0 Habis <p>Stok habis</p>
Klik Restok +3 3 Tersedia tombol baru TombolBeli jalan

Switch dan Match: cabang pertama yang benar

<Switch> memeriksa <Match> di dalamnya dari atas ke bawah dan menampilkan satu saja: yang pertama when-nya benar. Sisanya gak dirender sama sekali. Kalau gak ada yang benar, <Switch fallback={...}> yang tampil.

Karena itu urutannya penting. Kalau stok() < 3 ditaruh di atas stok() === 0, saat stok 0 kedua kondisi benar (0 juga kurang dari 3), dan yang dipakai yang di atas: labelnya Sisa sedikit, bukan Habis. Itu jawaban tebakannya. Taruh kondisi yang paling khusus paling atas.

Latihan kedua memakai bentuk yang sama untuk peran pengguna:

import { createSignal, Switch, Match } from "solid-js"

function App() {
  const [role] = createSignal("user")

  return (
    <Switch>
      <Match when={role() === "admin"}>
        <p>Admin Panel</p>
      </Match>
      <Match when={role() === "user"}>
        <p>Dashboard</p>
      </Match>
    </Switch>
  )
}

Role-nya "user", jadi yang tampil cuma <p>Dashboard</p>. Paragraf Admin Panel tetap ditulis di kodenya, tapi gak ada di halaman.

Ternary juga jalan, jadi kenapa Show?

Di Solid, {stok() > 0 ? <TombolBeli /> : <p>Stok habis</p>} juga bekerja dengan benar. Compiler Solid membungkus kondisinya sendiri, jadi cabangnya juga cuma dibuat ulang saat kondisinya berganti, bukan tiap stok berubah. Yang membuat Show lebih enak: namanya jelas, ada fallback, dan ada bentuk fungsi anak (bagian berikutnya). Latihan pertama memeriksa bahwa kodemu memakai Show, jadi di sana tulis <Show>, bukan ternary.

💡 Show dengan fungsi anak, dan keyed

<Show when={dipilih()} fallback={<p>Belum ada buku dipilih</p>}>
  {(buku) => <p>{buku().judul}</p>}
</Show>

Kalau isi Show berupa fungsi, Solid memanggilnya dengan nilai when yang sudah pasti truthy. Di Solid 1.9, buku di situ adalah getter, jadi dibaca buku().judul. Saat dipilih() berganti dari Laskar Pelangi ke Bumi Manusia, paragrafnya tetap elemen yang sama dan cuma teksnya yang diganti.

Dengan <Show when={dipilih()} keyed>, fungsinya menerima objeknya langsung (buku.judul), dan seluruh isinya dibuat ulang tiap kali dipilih() menjadi objek lain.

⚠️ Jebakan yang sering ketemu

TL;DR: <Show when={kondisi()} fallback={<p>...</p>}>isi</Show> menampilkan isinya saat kondisinya truthy dan fallback saat falsy, dan cuma menukar keduanya saat kondisinya berganti, jadi stok 4 ke 3 gak membuat ulang tombol Beli. <Switch> dengan beberapa <Match when={...}> menampilkan satu cabang saja: yang pertama benar, jadi taruh kondisi paling khusus di atas. Ternary juga jalan di Solid, tapi Show lebih jelas dan punya fallback. Fungsi anak Show menerima getter (buku()), atau nilainya langsung dengan keyed. Selalu panggil signal di when: when={loggedIn()}.

Yang akan kamu pelajari