List Rendering Solid — SolidJS

Solid menyediakan For dan Index untuk merender list secara efisien. For import { For } from "solid-js" function App() { const [items] = createSignal(["Apel"…

Untuk merender daftar, Solid punya dua komponen bawaan: <For> dan <Index>. Keduanya menerima array lewat prop each dan sebuah fungsi yang mengubah tiap item jadi elemen. Bedanya ada di cara mereka mengenali baris: <For> mengenali baris dari itemnya, <Index> dari posisinya. Bayangin rak di Toko Buku Kak Nadia, dan Kak Nadia menempel catatan kecil "kado" untuk Laskar Pelangi. Cara For: catatannya ditempel di bukunya, jadi saat buku-buku disusun ulang, catatan itu ikut pindah bersama Laskar Pelangi. Cara Index: catatannya ditempel di sekat rak nomor 1, jadi saat buku disusun ulang, catatan itu tetap di sekat 1, di sebelah buku lain.

🧪 Tebakan cepat: daftar buku dirender dengan <Index>, tiap baris punya kotak catatan, dan kamu mengetik kado di baris pertama, Laskar Pelangi. Lalu urutannya dibalik. Catatan kado sekarang di sebelah Laskar Pelangi (baris 3) atau Cantik Itu Luka (baris 1)? Jawabannya ada di bagian "For vs Index saat urutannya berubah".

For: satu baris per item

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

function App() {
  const [buah] = createSignal(["Apel", "Mangga", "Jeruk"])

  return (
    <ul>
      <For each={buah()}>
        {(item) => <li>{item}</li>}
      </For>
    </ul>
  )
}

Hasilnya satu <ul> berisi <li>Apel</li>, <li>Mangga</li>, <li>Jeruk</li>, sesuai urutan datanya.

buah().map(item => <li>{item}</li>) juga tampil sama, tapi tiap kali array-nya berubah, .map() membuat ulang semua baris. <For> cuma membuat baris untuk item yang baru. Latihan pertama memeriksa bahwa barisnya lahir dari <For>.

Index: satu baris per posisi

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

function App() {
  const [numbers] = createSignal([10, 20, 30])

  return (
    <ul>
      <Index each={numbers()}>
        {(num, i) => <li>{i + 1}. {num()}</li>}
      </Index>
    </ul>
  )
}

Hasilnya 1. 10, 2. 20, 3. 30. Peran kedua parameternya kebalikan dari For:

<For> <Index>
Baris dikenali dari itemnya (objek yang sama) posisinya (urutan ke berapa)
Parameter pertama nilai: item getter: num()
Parameter kedua getter: i() angka biasa: i
Cocok untuk daftar objek yang bisa diurutkan, ditambah, dihapus daftar yang posisinya tetap tapi isinya berubah

Ini latihan kedua. Kalau angka di posisi 2 diganti dari 20 jadi 25, Index cuma mengganti teks di baris 2. For membuat baris baru, karena 25 adalah item yang belum pernah ia lihat.

For vs Index saat urutannya berubah

Daftar buku Toko Buku Kak Nadia, dengan kotak catatan di tiap baris:

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

function App() {
  const [buku, setBuku] = createSignal([
    { judul: "Laskar Pelangi", harga: 89000 },
    { judul: "Bumi Manusia", harga: 120000 },
    { judul: "Cantik Itu Luka", harga: 95000 },
  ])
  const balik = () => setBuku(b => [...b].reverse())
  const diskon = () => setBuku(b => b.map(x => x.judul === "Laskar Pelangi" ? { ...x, harga: 79000 } : x))

  return (
    <div>
      <button onClick={balik}>Balik urutan</button>
      <button onClick={diskon}>Diskon Laskar Pelangi</button>
      <ul>
        <For each={buku()}>
          {(b, i) => (
            <li>
              {i() + 1}. {b.judul} · Rp{b.harga}
              <input placeholder="catatan" />
            </li>
          )}
        </For>
      </ul>
    </div>
  )
}

Versi Index-nya sama, dengan <Index each={buku()}>, {i + 1}, {b().judul}, dan {b().harga}. Ketik kado di baris Laskar Pelangi, lalu klik Balik urutan. Diuji di Solid 1.9:

<For> <Index>
Teks sesudah dibalik 1. Cantik Itu Luka, 2. Bumi Manusia, 3. Laskar Pelangi sama
Elemen <li> dipindah, ikut bukunya diam di tempat, teksnya diganti
Catatan kado di baris Laskar Pelangi, sekarang nomor 3 di baris 1, sebelah Cantik Itu Luka
Baris yang dibuat baru 0 0

Dengan Index, kado tetap di baris pertama, dan sekarang ada di sebelah Cantik Itu Luka. Itu jawaban tebakannya. Barisnya gak pernah pindah, cuma teks di dalamnya yang diganti.

Satu hal lagi tentang For: dia mengenali item dari objeknya, bukan dari isinya. Tombol Diskon Laskar Pelangi mengganti objeknya dengan objek baru, { ...x, harga: 79000 }, dan For menganggapnya item baru: barisnya dibuat ulang dan catatan kado hilang. Index cuma mengganti teks harganya jadi Rp79000.

⚠️ Jebakan yang sering ketemu

TL;DR: <For each={buah()}>{(item, i) => <li>{item}</li>}</For> membuat satu baris per item: item berupa nilai, nomor urut berupa getter i(), dan barisnya dikenali dari objeknya, jadi saat urutan berubah elemennya ikut pindah bersama isinya (dan objek baru berarti baris baru). <Index each={numbers()}>{(num, i) => <li>{i + 1}. {num()}</li>}</Index> kebalikannya: item berupa getter num(), nomor urut berupa angka, dan barisnya terikat ke posisi, jadi yang berubah cuma teksnya. Pakai For untuk daftar objek yang diurutkan, ditambah, dihapus; Index untuk daftar yang posisinya tetap tapi isinya berganti.

Yang akan kamu pelajari