Di Solid, props.children bukan isi yang sudah jadi. Dia getter: setiap kali dibaca, Solid membuat anak-anaknya dari awal, menjalankan lagi komponen di dalamnya, dan membuat elemen DOM baru. Helper children(() => props.children) membacanya sekali, lalu menyimpan hasilnya supaya bisa dibaca berkali-kali. Bayangin Kak Nadia memesan isi rak ke penerbit. Kalau setiap kali dia bertanya "isinya apa?" penerbit mencetak satu set buku baru, gudangnya cepat penuh buku yang gak pernah dipajang. children() itu menerima kirimannya sekali, lalu menghitung dan memajang dari kardus yang sama.
🧪 Tebakan cepat: komponen
Rakmembacaprops.childrendua kali: sekali untuk menghitung jumlah buku, sekali untuk menampilkannya. Di dalamnya ada duaKartuBuku, dan masing-masing mencetakKartuBuku jalanke console. Berapa baris yang tercetak? Jawabannya ada di bagian "props.children adalah getter".
props.children adalah getter
function KartuBuku(props) {
console.log("KartuBuku jalan:", props.judul)
return <div class="kartu">{props.judul}</div>
}
function Rak(props) {
return (
<section class="rak">
<p>Isi rak: {props.children.length} buku</p>
<div class="isi">{props.children}</div>
</section>
)
}
function App() {
return (
<Rak>
<KartuBuku judul="Laskar Pelangi" />
<KartuBuku judul="Bumi Manusia" />
</Rak>
)
}
Diuji di Solid 1.9.17, console-nya:
KartuBuku jalan: Laskar Pelangi
KartuBuku jalan: Bumi Manusia
KartuBuku jalan: Laskar Pelangi
KartuBuku jalan: Bumi Manusia
Empat baris, untuk dua kartu. Itu jawaban tebakannya. Halamannya benar, Isi rak: 2 buku dan dua kartu, tapi satu set kartu dibuat cuma untuk dihitung lalu dibuang. Compiler Solid mengubah isi <Rak>...</Rak> jadi getter children, jadi props.children.length membuat satu set, dan {props.children} membuat set kedua.
children(): resolve sekali, baca berkali-kali
import { children } from "solid-js"
function Rak(props) {
const kartu = children(() => props.children)
return (
<section class="rak">
<p>Isi rak: {kartu.toArray().length} buku</p>
<div class="isi">{kartu()}</div>
</section>
)
}
Sekarang console-nya cuma dua baris, satu per kartu.
children(() => props.children)menerima fungsi yang membacaprops.children. Panggil sekali, di badan komponen.kartu()mengembalikan hasil yang sudah jadi: elemennya langsung kalau anaknya satu, array kalau lebih. Dibaca berapa kali pun, isinya elemen yang sama.kartu.toArray()selalu mengembalikan array, cocok untuk.lengthatau perulangan.
Bentuk latihan pelajaran ini:
import { children } from "solid-js"
function Wrapper(props) {
const resolved = children(() => props.children)
return <div class="wrapper">{resolved()}</div>
}
function App() {
return (
<Wrapper>
<p>Konten child</p>
</Wrapper>
)
}
Wrappergak tahu isinya. Dia menyediakan<div class="wrapper">lalu menaruh kiriman pemanggilnya di sana, jadi sesudahclass="wrapper">langsung ada{.Appmemakai<Wrapper>dan membungkus<p>Konten child</p>di dalamnya. Hasilnya<div class="wrapper"><p>Konten child</p></div>.
Mengolah children: kenapa harus di-resolve dulu
Rak mau menandai setiap kartu dengan kelas di-rak:
function Rak(props) {
const kartu = children(() => props.children)
createEffect(() => {
kartu.toArray().forEach((el) => el.classList.add("di-rak"))
})
return <section class="rak">{kartu()}</section>
}
Diuji di Solid 1.9.17: dua kartu di halaman jadi class="kartu di-rak". Kalau efeknya menulis props.children.forEach(...), bacaan itu membuat set kartu baru, dan kelasnya mendarat di kartu yang gak pernah tampil. Kartu di halaman tetap class="kartu". Itu maksud "meresolve lazy evaluation": props.children baru dibuat saat dibaca, dan children() mengubahnya jadi elemen DOM nyata yang bisa kamu hitung, ulangi, dan olah.
Kalau komponenmu cuma menaruh {props.children} sekali di JSX, helper ini gak perlu. Pakai saat kamu membaca anak-anaknya lebih dari sekali, atau mau memeriksa dan mengolahnya.
⚠️ Jebakan yang sering ketemu
- Membaca
props.childrendua kali. Komponen di dalamnya jalan dua kali, dan elemen yang kamu olah bukan yang tampil. children(props.children)tanpa fungsi. Helper-nya butuh fungsi, jadi ini berhenti dengan TypeError. Tulischildren(() => props.children).- Memanggil
children()di dalam JSX atau efek. Tiap panggilan membaca getter-nya lagi. Panggil sekali di badan komponen, simpan di variabel, lalu baca variabel itu. - Bentuk yang diperiksa latihannya. Sesudah
class="wrapper">langsung{...}, bukan teks yang diketik. Dan pemanggilnya ditulis<Wrapper>tanpa atribut, dengan isi sebelum</Wrapper>.
TL;DR: props.children di Solid adalah getter: tiap bacaan membuat anak-anaknya dari awal, jadi membacanya dua kali menjalankan komponen di dalamnya dua kali (empat baris KartuBuku jalan untuk dua kartu). const resolved = children(() => props.children), dipanggil sekali di badan komponen, me-resolve-nya jadi elemen nyata: resolved() untuk menampilkan, resolved.toArray() untuk menghitung atau mengolah, dan semuanya elemen yang sama dengan yang tampil. Latihannya: <div class="wrapper">{resolved()}</div> di Wrapper, dipakai App sebagai <Wrapper><p>Konten child</p></Wrapper>.