Coba liat feed timeline Twitter/X. Ratusan tweet berderet dari atas ke bawah, masing-masing punya struktur sama (avatar, nama, isi, tombol like) tapi konten beda. Bayangin nulis manual: <Tweet>...</Tweet> 100x — gila. Solusinya: data array + .map(). Satu kali define struktur tweet, JavaScript yang generate JSX-nya buat tiap item. Pattern ini ada di hampir semua aplikasi React — list produk, chat messages, comment thread, search results — semua dasarnya array.map().
💡 Anatomi pattern. Data → JSX.
array.map(item => <Component item={item} />). Tiap iterasi return JSX, hasil akhirnya array of JSX yang React render berurutan. Sederhana tapi powerful — fundamental yang dipake tiap hari.
function App() {
const buah = ["Apel", "Mangga", "Jeruk"]
return (
<ul>
{buah.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
)
}
Key Prop — WAJIB Unique
Setiap elemen dalam list WAJIB punya key unik. Key bantu React identify item mana yang nambah/hapus/berubah pas re-render — bukan dekorasi, ini optimisasi performa + correctness.
// JELEK — pakai index
{items.map((item, index) => <Item key={index} {...item} />)}
// BAGUS — pakai ID unik dari data
{items.map(item => <Item key={item.id} {...item} />)}
Kenapa ID > index? Pas urutan list berubah (sort, filter, prepend), index "Item A" berubah dari 0 ke 2 → React kira "key 0 sekarang isinya Item C" → state internal komponen ke-mix. Pakai ID unik = identitas konsisten.
List dari Data Object
const siswa = [
{ id: 1, name: "Andi", nilai: 85 },
{ id: 2, name: "Budi", nilai: 92 },
{ id: 3, name: "Cici", nilai: 78 },
]
return (
<table>
{siswa.map(s => (
<tr key={s.id}>
<td>{s.name}</td>
<td>{s.nilai}</td>
</tr>
))}
</table>
)
Filter + Map = List Pattern
// Tampilin hanya yang lulus
{siswa
.filter(s => s.nilai >= 75)
.map(s => <li key={s.id}>{s.name}</li>)
}
🎭 Analogi sehari-hari
array.map() itu kayak mesin fotokopi sekolah. Kasih satu master template (komponen <Tweet>/<Card>) plus tumpukan data berbeda — mesin output tiap halaman dengan template sama tapi isi beda. key itu kayak nomor urut di belakang tiap fotokopi — biar pas guru harus susun ulang (sort/filter), gampang nemuin "ini tugas siapa". Tanpa nomor urut, guru bingung pas urutan diacak — itu yang React rasain pas key gak unik atau pakai index yang berubah.
⚠️ Jebakan yang sering ditemui
- Pakai index sebagai key + urutan list bisa berubah = bug klasik (state internal Item ke-mix). Pakai ID unik dari data.
- Lupa
keyprop — warning di console, perf turun. SELALU kasih key di.map(). key={Math.random()}— beda tiap render = React kira "ini item baru terus" = re-render mahal + lose state. JANGAN.- Key dari nama — kalau ada 2 user nama sama = duplicate key error. Pakai ID database.
- Map tanpa return —
arr.map(item => { <li>{item}</li> })(kurung kurawal!) = return undefined. Hapus{}atau pakaireturn. - Nested map tanpa unique key — list dalam list, key di OUTER cukup unique di scope outer, INNER unique di scope inner. Bisa ulang.
forEachinstead ofmap—forEachgak return array, jadi gak nge-render apa-apa. WAJIBmap.
🎯 Pilih key apa?
- Data dari database →
item.id(paling umum, paling aman)- Data dari API tanpa ID →
item.uuidatau combine field unik (${item.name}-${item.email})- List static yang gak akan berubah urutannya →
indexboleh (cuma kalau YAKIN gak ada add/remove/sort)- Generated client-side →
crypto.randomUUID()saat dibuat, simpan di stateAturan: cari nilai yang STABIL + UNIK per item, ngga pernah berubah selama item itu hidup di list.
TL;DR: Tampilin list di React = array.map(item => <Component key={item.id} ... />). WAJIB key unik per item — pakai ID dari data, bukan index (kecuali list 100% static). Combine filter + map buat conditional list. Lupa return di map((item) => { ... }) = bug klasik. forEach gak balikin JSX, harus map.