Me-render List
Anda mungkin ingin menampilkan beberapa komponen yang mirip dari sebuah kumpulan data. Anda dapat menggunakan method senarai (array) JavaScript untuk memanipulasi sebuah senarai data. Pada halaman ini, Anda akan menggunakan method filter()
dan map()
dengan React untuk menyaring dan mengubah senarai data tersebut menjadi sebuah senarai komponen.
You will learn
- Bagaimana me-render komponen-komponen dari sebuah senarai menggunakan method
map()
- Bagaimana me-render beberapa komponen spesifik menggunakan method
filter()
- Kapan dan mengapa menggunakan React keys
Me-render data dari senarai
Misalkan Anda memiliki daftar konten seperti berikut.
<ul>
<li>Creola Katherine Johnson: mathematician</li>
<li>Mario José Molina-Pasquel Henríquez: chemist</li>
<li>Mohammad Abdus Salam: physicist</li>
<li>Percy Lavon Julian: chemist</li>
<li>Subrahmanyan Chandrasekhar: astrophysicist</li>
</ul>
Semua anggota dari daftar tersebut memiliki format yang sama. Perbedaan hanya terletak pada isi konten, lebih tepatnya data mereka. Pada beberapa situasi, Anda mungkin harus menampilkan beberapa komponen yang sama dengan data yang berbeda saat membangun antarmuka, seperti daftar komentar atau galeri foto profil. Dalam situasi-situasi tersebut, Anda bisa menyimpan data tersebut ke dalam objek atau senarai JavaScript dengan menggunakan method map()
dan filter()
yang kemudian akan digunakan untuk me-render beberapa komponen.
Contoh untuk membuat sebuah daftar dari sebuah senarai:
- Pindahkan data ke sebuah senarai:
const people = [
'Creola Katherine Johnson: mathematician',
'Mario José Molina-Pasquel Henríquez: chemist',
'Mohammad Abdus Salam: physicist',
'Percy Lavon Julian: chemist',
'Subrahmanyan Chandrasekhar: astrophysicist'
];
- Petakan dengan menggunakan method
map()
setiap anggotapeople
ke sebuah senarai node JSX,listItems
:
const listItems = people.map(person => <li>{person}</li>);
- Kembalikan
listItems
dari komponen Anda dengan membungkusnya terlebih dahulu dengan elemen<ul>
:
return <ul>{listItems}</ul>;
Hasilnya seperti berikut:
const people = [ 'Creola Katherine Johnson: mathematician', 'Mario José Molina-Pasquel Henríquez: chemist', 'Mohammad Abdus Salam: physicist', 'Percy Lavon Julian: chemist', 'Subrahmanyan Chandrasekhar: astrophysicist' ]; export default function List() { const listItems = people.map(person => <li>{person}</li> ); return <ul>{listItems}</ul>; }
Perhatikan bahwa sandbox di atas menampilkan pesan kesalahan:
Anda akan mempelajari cara memperbaiki kesalahan ini nanti. Untuk saat ini, kita akan menambahkan struktur ke data Anda.
Menyaring senarai
Kita bisa menambahkan struktur ke data ini.
const people = [{
id: 0,
name: 'Creola Katherine Johnson',
profession: 'mathematician',
}, {
id: 1,
name: 'Mario José Molina-Pasquel Henríquez',
profession: 'chemist',
}, {
id: 2,
name: 'Mohammad Abdus Salam',
profession: 'physicist',
}, {
name: 'Percy Lavon Julian',
profession: 'chemist',
}, {
name: 'Subrahmanyan Chandrasekhar',
profession: 'astrophysicist',
}];
Misalkan Anda hanya ingin menampilkan orang yang memiliki profesi 'chemist'
. Anda dapat menggunakan method filter()
dari JavaScript untuk mendapatkan daftar tersebut. Method ini menerima masukan berupa sebuah senarai, kemudian menguji setiap anggota dari senarai tersebut dengan sebuah fungsi uji (fungsi yang hanya mengembalikan nilai true
(benar) atau false
(salah)), lalu mengembalikan sebuah senarai baru yang terdiri atas anggota-anggota yang lolos uji (memperoleh nilai true
).
Anda hanya menginginkan orang yang memiliki profession
berupa 'chemist'
. Oleh karena itu, fungsi ujinya adalah (person) => person.profession === 'chemist'
. Langkahnya seperti berikut:
- Buatkan sebuah senarai baru yang terdiri atas orang-orang berprofesi
chemists
, dengan memanggil methodfilter()
terhadap senaraipeople
dengan syaratperson.profession === 'chemist'
:
const chemists = people.filter(person =>
person.profession === 'chemist'
);
- Petakan setiap anggota dari senarai
chemists
menggunakan methodmap()
, yang sudah kita pelajari, menjadi sebuah senarai node JSX,listItems
:
const listItems = chemists.map(person =>
<li>
<img
src={getImageUrl(person)}
alt={person.name}
/>
<p>
<b>{person.name}:</b>
{' ' + person.profession + ' '}
known for {person.accomplishment}
</p>
</li>
);
- Kembalikan
listItems
dari komponen Anda dengan membungkusnya terlebih dahulu dengan elemenul
:
return <ul>{listItems}</ul>;
Hasil akhirnya seperti berikut:
import { people } from './data.js'; import { getImageUrl } from './utils.js'; export default function List() { const chemists = people.filter(person => person.profession === 'chemist' ); const listItems = chemists.map(person => <li> <img src={getImageUrl(person)} alt={person.name} /> <p> <b>{person.name}:</b> {' ' + person.profession + ' '} known for {person.accomplishment} </p> </li> ); return <ul>{listItems}</ul>; }
Menjaga urutan dengan key
Perhatikan bahwa setiap sandbox di atas menampilkan pesan kesalahan di konsol:
Anda harus memberikan setiap anggota dari senarai sebuah key
—sebuah string atau angka yang dapat mengidentifikasi setiap anggota secara unik:
<li key={person.id}>...</li>
Key
memberi tahu React mengenai hubungan antara sebuah komponen dengan sebuah anggota senarai. Hal ini krusial jika anggota senarai bisa berubah posisi (contohnya karena proses pengurutan (sorting)), ditambah, atau dihapus. Sebuah key
yang baik dapat membantu React untuk mengetahui apa yang telah terjadi dan menentukan langkah optimal saat memperbarui pohon DOM.
Sebaiknya, key
terkandung di dalam data Anda:
export const people = [{ id: 0, // Digunakan sebagai key pada JSX name: 'Creola Katherine Johnson', profession: 'mathematician', accomplishment: 'spaceflight calculations', imageId: 'MK3eW3A' }, { id: 1, // Digunakan sebagai key pada JSX name: 'Mario José Molina-Pasquel Henríquez', profession: 'chemist', accomplishment: 'discovery of Arctic ozone hole', imageId: 'mynHUSa' }, { id: 2, // Digunakan sebagai key pada JSX name: 'Mohammad Abdus Salam', profession: 'physicist', accomplishment: 'electromagnetism theory', imageId: 'bE7W1ji' }, { id: 3, // Digunakan sebagai key pada JSX name: 'Percy Lavon Julian', profession: 'chemist', accomplishment: 'pioneering cortisone drugs, steroids and birth control pills', imageId: 'IOjWm71' }, { id: 4, // Digunakan sebagai key pada JSX name: 'Subrahmanyan Chandrasekhar', profession: 'astrophysicist', accomplishment: 'white dwarf star mass calculations', imageId: 'lrWQx8l' }];
Deep Dive
Bagaimana kalau setiap anggota senarai membutuhkan bukan hanya satu, tetapi beberapa node DOM?
Sintaksis singkat <>...</>
Fragment tidak memberikan tempat untuk key
, sehingga Anda harus membungkus ke dalam sebuah <div>
atau menggunakan sintaksis <Fragment>
yang lebih panjang:
import { Fragment } from 'react';
// ...
const listItems = people.map(person =>
<Fragment key={person.id}>
<h1>{person.name}</h1>
<p>{person.bio}</p>
</Fragment>
);
Pada akhirnya, Fragment
akan hilang dari DOM dan hanya menyisakan <h1>
, <p>
, <h1>
, <p>
, dan seterusnya, pada contoh di atas.
Bagaimana Anda memperoleh key
Sumber data yang berbeda akan memberikan key
yang berbeda juga, contoh:
- Data dari basis data: Jika data yang digunakan berasal dari basis data, ID dapat digunakan sebagai
key
karena sifatnya yang sudah unik. - Data lokal: Jika data dihasilkan dan disimpan secara lokal (seperti catatan pada aplikasi penulisan catatan), Anda dapat menggunakan counter yang bertambah,
crypto.randomUUID()
, atau library sepertiuuid
.
Aturan key
Key
harus bersifat unik antar-sibling. Namun,key
yang sama bisa digunakan lagi di senarai yang berbeda.Key
tidak boleh berubah atau fungsinya akan hilang! Jangan membuatkey
di saat me-render.
Mengapa React membutuhkan key
?
Bayangkan jika file yang ada di komputer Anda tidak memiliki nama. Sebagai pengganti, Anda merujuk ke file tersebut dengan urutannya—file pertama, file kedua, dan seterusnya. Saat file pertama dihapus, file kedua akan menjadi file pertama, kemudian file ketiga akan menjadi file kedua, dan seterusnya. Perujukan file menjadi tidak konsisten.
Nama file pada folder dan key
pada JSX memiliki tujuan yang serupa. Mereka membantu kita mengidentifikasi anggota senarai dan membedakan mereka antar-sibling. Key
yang baik tidak hanya memberikan informasi mengenai posisi item di dalam senarai, tetapi juga membantu React mengidentifikasi item tersebut sepanjang hidupnya.
Recap
Pada halaman ini, Anda telah mempelajari:
- Bagaimana memindahkan data dari komponen ke senarai atau objek.
- Bagaimana membuat himpunan komponen yang serupa dengan menggunakan method
map()
. - Bagaimana membuat senarai dari item yang memenuhi suatu kondisi menggunakan method
filter()
. - Mengapa dan bagaimana menentukan
key
untuk setiap komponen pada sebuah collection sehingga React bisa melakukan render yang optimal meskipun terdapat perubahan pada posisi atau data.
Challenge 1 of 4: Membagi sebuah daftar menjadi dua
Pada contoh ini, terdapat sebuah daftar orang.
Anda diminta untuk menampilkan dua daftar berbeda, satu setelah yang lain: Chemists dan Bukan Chemist. Seperti sebelumnya, Anda bisa melihat apakah seseorang berprofesi sebagai chemist dengan menggunakan person.profession === 'chemist'
.
import { people } from './data.js'; import { getImageUrl } from './utils.js'; export default function List() { const listItems = people.map(person => <li key={person.id}> <img src={getImageUrl(person)} alt={person.name} /> <p> <b>{person.name}:</b> {' ' + person.profession + ' '} known for {person.accomplishment} </p> </li> ); return ( <article> <h1>Scientists</h1> <ul>{listItems}</ul> </article> ); }