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 })menampilkanStok: {stok}. Induknya mengirimstok={stok()}yang awalnya 4, lalu tombolBeli 1menurunkan signal-nya jadi 3. Kartunya menampilkanStok: 4atauStok: 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" />
}
<Greeting nama="Andi" />mengirim prop bernamanamadengan nilai"Andi". Pemanggilnya yang menentukan nilainya.function Greeting(props)menerima satu objek. Isinya{ nama: "Andi" }.{props.nama}dibaca di dalam<h2>, jadi tampilHalo, Andi!. Ini juga bentuk jawaban latihan pelajaran ini.- Teks dikirim dalam tanda kutip. Nilai lain dikirim lewat kurung kurawal:
harga={89000},stok={stok()}. Kalau ditulisharga="89000", yang terkirim string.
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();
}
})
judulnilai biasa, karena"Laskar Pelangi"gak pernah berubah.stokjadi getter: fungsi yang jalan tiap kali properti itu dibaca. Jadi tiapprops.stokdibaca, Solid memanggilstok()milikAppsaat itu juga.{props.stok}di dalam JSX dibaca ulang tiap signalstokberubah, persis seperti{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>
)
}
mergeProps({ stok: 0 }, props)menggabungkan objek bawaan dengan props. Kalauprops.stokada, itu yang dipakai. Kalau gak ada,0.- Hasilnya tetap objek yang membaca ulang, jadi
{p.stok}tetap mengikuti signal induknya. Jangan destructure hasilnya juga:const { stok } = mergeProps(...)membaca sekali, sama seperti tadi. - Saudaranya,
splitProps(props, ["judul"]), membagi props jadi dua kelompok (misalnya yang dipakai sendiri dan sisanya untuk diteruskan) tanpa kehilangan pembacaan ulang.
⚠️ Jebakan yang sering ketemu
- Destructuring di parameter.
function KartuBuku({ stok })menampilkan nilai pertama selamanya. Tulisfunction KartuBuku(props)dan bacaprops.stok. - Menyimpan prop di variabel dulu.
const s = props.stokdi badan komponen juga membaca sekali. Baca langsung di JSX. - Nama prop gak sama. Induk mengirim
nama, anak membacaprops.name: hasilnyaundefined, dan sapaannya jadiHalo, !. - Mengetik nama langsung di judul.
<h2>Halo, Andi!</h2>tampil benar, tapi latihannya memeriksa bahwa namanya dibaca dariprops.namadi dalam<h2>.
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.