Props Solid — SolidJS

Props di Solid adalah reactive proxy — jangan di-destructure karena akan kehilangan reactivity! Menggunakan Props function Greeting(props) { return Halo…

Props adalah data yang dikirim komponen induk ke komponen anaknya, ditulis seperti atribut HTML: <KartuBuku judul="Laskar Pelangi" stok={stok()} />. Di Solid, komponen anak menerima semuanya dalam satu objek bernama props, lalu membacanya dengan titik: props.judul, props.stok. Bayangin kartu buku di rak Toko Buku Kak Nadia punya jendela kecil yang mengintip buku catatan stok di gudang. Tiap kali ada yang melirik jendela itu, yang terlihat angka terbaru di catatan. Kalau angkanya malah disalin ke kartu pakai pulpen, salinan itu gak pernah berubah walau catatannya berubah. Membaca props.stok itu melirik jendela. Destructuring, ({ stok }), itu menyalin pakai pulpen.

🧪 Tebakan cepat: function KartuBuku({ judul, stok }) menampilkan Stok: {stok}. Induknya mengirim stok={stok()} yang awalnya 4, lalu tombol Beli 1 menurunkan signal-nya jadi 3. Kartunya menampilkan Stok: 4 atau Stok: 3? Jawabannya ada di bagian "Jangan di-destructure".

Mengirim dan menerima props

function Greeting(props) {
  return <h2>Halo, {props.nama}!</h2>
}

function App() {
  return <Greeting nama="Andi" />
}

props adalah objek yang membaca ulang

import { createSignal } from "solid-js"

function KartuBuku(props) {
  console.log("KartuBuku jalan")
  return (
    <div class="kartu">
      <h2>{props.judul}</h2>
      <p>Stok: {props.stok}</p>
    </div>
  )
}

function App() {
  const [stok, setStok] = createSignal(4)
  return (
    <div>
      <button onClick={() => setStok(s => s - 1)}>Beli 1</button>
      <KartuBuku judul="Laskar Pelangi" stok={stok()} />
    </div>
  )
}

Compiler Solid 1.9 menulis pemakaian KartuBuku itu begini:

_$createComponent(KartuBuku, {
  judul: "Laskar Pelangi",
  get stok() {
    return stok();
  }
})
Kejadian signal stok di App Kartu (props.stok) Console
Halaman dibuka 4 Stok: 4 KartuBuku jalan
Klik Beli 1 3 Stok: 3
Klik lagi 2 Stok: 2

Fungsi KartuBuku tetap jalan sekali. Yang membaca ulang cuma {props.stok} di JSX-nya.

Jangan di-destructure

function KartuBuku({ judul, stok }) {
  return (
    <div class="kartu">
      <h2>{judul}</h2>
      <p>Stok: {stok}</p>
    </div>
  )
}

Destructuring di parameter membaca props.stok sekali, saat fungsi KartuBuku jalan, lalu menyimpan angkanya di variabel biasa. Fungsi itu gak jalan lagi, jadi variabel stok tetap 4 selamanya. Setelah Beli 1, App sudah 3, tapi kartunya tetap Stok: 4. Itu jawaban tebakannya.

Hal yang sama terjadi untuk const { judul, stok } = props di badan komponen, dan untuk const stokAwal = props.stok di luar JSX. Semuanya membaca sekali. Aturannya: baca props.sesuatu langsung di tempat nilainya dipakai.

Nilai bawaan dengan mergeProps

Kalau sebuah prop gak dikirim, nilainya undefined dan gak tampil apa-apa: <KartuBuku judul="Cantik Itu Luka" /> menampilkan Stok: saja. Untuk nilai bawaan, pakai mergeProps:

import { mergeProps } from "solid-js"

function KartuBuku(props) {
  const p = mergeProps({ stok: 0 }, props)
  return (
    <div class="kartu">
      <h2>{p.judul}</h2>
      <p>Stok: {p.stok}</p>
    </div>
  )
}

⚠️ Jebakan yang sering ketemu

TL;DR: Props dikirim seperti atribut (<Greeting nama="Andi" />) dan diterima sebagai satu objek, function Greeting(props), lalu dibaca di JSX: <h2>Halo, {props.nama}!</h2>. Di Solid, prop yang nilainya dari signal dikirim sebagai getter, jadi {props.stok} di JSX ikut berubah walau fungsi komponennya jalan sekali. Destructuring (({ stok }) atau const { stok } = props) membaca sekali dan memutus pembacaan ulang itu: kartunya macet di nilai pertama. Untuk nilai bawaan, mergeProps({ stok: 0 }, props), dan untuk membagi props, splitProps, keduanya tanpa kehilangan reaktivitas, selama hasilnya gak di-destructure.

Yang akan kamu pelajari