Terakhir diperbarui: 2024-02-26
Konsep dalam penggunaan ReactJS untuk antarmuka pengguna ada beberapa yang penting, diantaranya tentang komponen, JavaScript XML (JSX), membuat component dan penggunaan props.
Sebelum memulai codelab ini, sebaiknya Anda memiliki pengetahuan dasar tentang:
Komponen merupakan salah satu konsep inti dari React. Komponen adalah pondasi di mana Anda bangun antarmuka pengguna (UI). Anda dapat membayangkan komponen sebagai balok-balok lego yang menyusun UI. Di dalam web, HTML memungkinkan kita membuat dokumen-dokumen terstruktur yang kaya dengan kumpulan tag bawaannya seperti h1
dan li
seperti berikut ini:
<article>
<h1>Komponen Pertama Saya</h1>
<ol>
<li>Komponen: Pembangun Balok UI</li>
<li>Mendefinisikan suatu Komponen</li>
<li>Menggunakan suatu Komponen</li>
</ol>
</article>
Markup ini merepresentasikan artikel article
, heading h1
dan daftar isi (yang disingkat) sebagai daftar yang tersusun ol
. Markup seperti ini, digabung dengan CSS untuk style, dan JavaScript untuk interaktivitas, berada di belakang setiap sidebar, avatar, modal, dropdown—setiap potongan UI yang Anda liat di dalam web.
React memungkinkan Anda menggabung markup, CSS, dan JavaScript Anda menjadi "komponen" yang dibuat khusus, elemen UI yang dapat digunakan kembali untuk aplikasi Anda. Daftar isi yang Anda lihat di atas dapat diubah menjadi sebuah komponen TableOfContents
yang dapat Anda render pada setiap halaman. Dari belakang, itu tetap menggunakan tag HTML yang sama seperti article
, h1
, dan lain-lain.
Sama seperti tag HTML, Anda dapat menggabung, mengurut, dan menyusun bertingkat komponen untuk mendesain halaman penuh. Misalnya, halaman yang terdapat komponen-komponen React seperti berikut ini:
<PageLayout>
<NavigationHeader>
<SearchBar />
<Link to="/docs">Docs</Link>
</NavigationHeader>
<Sidebar />
<PageContent>
<TableOfContents />
<DocumentationText />
</PageContent>
</PageLayout>
Seiring berkembangnya proyek, Anda dapat memperhatikan bahwa banyak desain yang bisa dikomposisi dengan menggunakan ulang komponen-komponen yang sudah Anda buat, mempercepat pengembangan proyek Anda. Daftar isi di atas bisa disertakan pada layar apa pun dengan TableOfContents
. Anda bisa memulai proyek dengan cepat menggunakan ribuan komponen-komponen siap pakai yang dibagi oleh komunitas open source React seperti Chakra UI dan Material UI.
Setelah dari codelab atau pertemuan kedua, Anda telah mulai membuat project pertama. Selesaikan langkah-langkah praktikum berikut ini menggunakan editor Visual Studio Code (VS Code) atau code editor lain kesukaan Anda. Jawablah di laporan praktikum Anda pada setiap soal yang ada di beberapa langkah praktikum ini.
Buatlah folder baru bernama 03-belajar-komponen
lalu di dalam folder tersebut, jalankan terminal dengan mengetikkan perintah berikut:
npx create-next-app
Buatlah folder baru dan file baru di src/components/profile.tsx
lalu ketik kode berikut ini.
import Image from "next/image";
export default function Profile() {
return (
<Image
src="https://i.imgur.com/MK3eW3Am.jpg"
alt="Katherine Johnson"
width={100}
height={100}
style={{
maxWidth: "100%",
height: "auto",
margin: "13px"
}}
/>
);
}
Kode tersebut menggunakan komponen Image
bawaan dari Next.js.
Lakukan import komponen Profile
ke src/app/page.tsx
import Profile from "../components/profile";
Komponen adalah fungsi JavaScript biasa, sehingga Anda bisa menjaga beberapa komponen di dalam file yang sama. Ini nyaman ketika komponen-komponen relatif kecil atau saling terkait secara erat. Jika file ini mulai memiliki sangat banyak komponen, Anda bisa memindahkan komponen Profile ke suatu file yang berbeda. Anda akan belajar bagaimana cara melakukan ini segera pada bagian codelab ini berikutnya.
Karena komponen-komponen Profile
di-render di dalam Gallery
—bahkan beberapa kali!—kita dapat mengatakan bahwa Gallery
adalah sebuah komponen induk, yang me-render setiap Profile
sebagai sebuah "anak". Ini merupakan bagian ajaib dari React: Anda bisa mendefinisikan suatu komponen sekali, kemudian digunakan di banyak tempat dan sebanyak yang Anda suka.
Keajaiban komponen terletak pada kemampuannya yang dapat digunakan kembali. Anda dapat membuat komponen yang disusun dengan komponen lain. Namun, ketika Anda menyusun komponen-komponen yang semakin banyak, seringkali lebih masuk akal untuk mulai membaginya ke dalam file-file yang berbeda. Dengan ini Anda menjaga file Anda agar tetap mudah dipindai dan digunakan kembali di banyak tempat.
Misalnya di dalam komponen Gallery
terdapat banyak komponen Profile
. Bagaimana jika Anda ingin mengubah landing screen di masa depan dan memasukkan daftar buku sains di sana? Atau meletakkan semua profil di tempat lain? Maka sebaiknya memindahkan komponen Gallery
dan Profile
dari file komponen root. Ini akan membuat lebih modular dan dapat digunakan kembali di file lain. Secara umum, Anda dapat memindahkan sebuah komponen dengan tiga langkah berikut ini:
.js
atau .tsx
baru untuk memasukkan komponen. Sebaiknya semua komponen diletakkan dalam folder yang sama yaitu components
.Ada dua cara utama untuk mengekspor nilai dengan JavaScript: default exports dan named exports. Sejauh ini, contoh kita hanya menggunakan default exports. Tapi Anda dapat menggunakan satu atau keduanya pada file yang sama. Sebuah file dapat menggunakan tidak lebih dari satu default export, tapi dapat menggunakan named exports sebanyak yang Anda suka.
Teknik untuk mengekspor komponen Anda harus sesuai dengan cara mengimpornya. Anda akan mendapatkan error jika Anda mencoba untuk mengimpor default exports dengan cara yang sama Anda menggunakan named exports. Tabel ini akan membantu Anda untuk memahaminya:
Sintaksis | Pernyataan Expor | Pernyataan Impor |
Default |
|
|
Named |
|
|
Ketika Anda menulis default imports, Anda dapat memberi nama apa saja setelah import
. Contoh, Anda dapat menulis import Banana from './Button.js'
dan itu akan tetap ketika Anda menggunakan export default
yang sama. Sebaliknya, dengan named imports, nama harus sama di kedua sisi. Itulah mengapa disebut named imports!
Kebanyakan developer seringkali menggunakan default exports
jika file yang diekspor hanya satu komponen, dan menggunakan named exports
jika mengekspor beberapa komponen dan nilai. Bagaimanapun gaya koding yang Anda gunakan, selalu beri nama yang berarti pada fungsi komponen Anda dan isi file tersebut. Komponen tanpa nama, seperti export default ()=>{}
, tidak disarankan karena membuat proses debug lebih sulit.
Selesaikan langkah-langkah praktikum berikut ini menggunakan editor Visual Studio Code (VS Code) atau code editor lain kesukaan Anda. Jawablah di laporan praktikum Anda pada setiap soal yang ada di beberapa langkah praktikum ini.
Buatlah file baru di src/components/gallery.tsx
berisi kode seperti berikut:
import Profile from "./profile";
export function Gallery() {
return (
<div className="columns-3">
<Profile />
<Profile />
<Profile />
</div>
);
}
Lakukan impor komponen di src/app/page.tsx
seperti berikut ini. Hapus kode komponen lama Profile
, lalu sesuaikan dengan komponen baru Gallery
yang telah dibuat.
import { Gallery } from "@/components/gallery";
...
React menggunakan logika rendering UI yang menakjubkan secara bersamaan, diantaranya ketika event di-handle, perubahan state, dan penyiapan data untuk ditampilkan pada halaman web.
React tidak mewajibkan untuk menggunakan JSX, tetapi paling banyak digunakan oleh developer karena sangat membantu secara visual ketika bekerja dengan UI bersama kode JavaScript. Selain itu juga mendukung React untuk menunjukkan jika terjadi error dan pesan warning.
JSX adalah perpanjangan sintaksis untuk menulis kode seperti HTML dalam file JavaScript. Meskipun ada beberapa cara lain, JSX lebih dipilih oleh sebagian besar developer React dan codebase karena kepadatannya.
Website selama ini dibuat dari HTML, CSS, dan JavaScript. Selama bertahun-tahun, pengembang website menaruh konten di HTML, desain di CSS, dan logika di JavaScript—tidak jarang di file yang berbeda. Konten dibangun di HTML sedangkan logika halaman disimpan secara terpisah dalam JavaScript seperti kode berikut:
HTML |
JavaScript |
Namun, seiring dengan situs yang makin interaktif, logika semakin menentukan konten. JavaScript mengatur HTML, Inilah mengapa dalam React, logika render dan markup berada di satu tempat yang sama—komponen.
Menggabungkan logika render dan markup untuk sebuah tombol memastikan mereka tersinkronasi dengan satu sama lain pada tiap perubahan. Sebaliknya, detil yang tidak berhubungan, markup untuk tombol dan sidebar, juga tidak terhubung dengan satu sama lain, membuat perubahan masing-masing menjadi lebih aman.
Masing-masing komponen React adalah fungsi JavaScript yang bisa memiliki markup yang di-render oleh React ke peramban. Komponen React menggunakan ekstensi sitaksis yang bernama JSX untuk merepresentasikan markup tersebut. JSX terlihat sangat mirip dengan HTML, namun lebih ketat dan dapat menampilkan informasi secara dinamis. Cara terbaik untuk memahami JSX adalah dengan langsung mengubah beberapa markup HTML menjadi JSX.
Anggap anda memiliki HTML yang valid seperti kode berikut:
<h1>Daftar Tugas Putri</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Putri"
class="photo"
>
<ul>
<li>Mengerjakan PR
<li>Pergi belanja
<li>Minum vitamin
</ul>
Dan anda ingin meletakkannya di komponen:
export default function TodoList() {
return (
// ???
)
}
Jika anda salin dan tempel secara langsung, maka dia tidak akan bekerja:
Ini dikarenakan JSX lebih ketat dan memiliki banyak peraturan dibandingkan HTML! Jika anda membaca pesan error yang tertera, pesan tersebut akan mengarahkanmu untuk memperbaiki markup, atau anda bisa mengikuti panduan berikut.
Untuk mengembalikan lebih dari satu elemen, bungkus mereka dengan satu tag parent.
Contohnya, anda dapat menggunakan tag div
<div>
<h1>Daftar Tugas Putri</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Putri"
class="photo"
>
<ul>
...
</ul>
</div>
Jika anda tidak ingin menambahkan div
pada markup, anda dapat menggunakan tag kosong saja seperti berikut:
<>
<h1>Daftar Tugas Putri</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Putri"
class="photo"
>
<ul>
...
</ul>
</>
Tag kosong di atas disebut Fragment. Fragments dapat menggabungkan beberapa tag tanpa memasukkan tag tersebut ke bagian dari HTML.
Semua tag JSX harus dapat ditutup tag tunggal seperti < img >
harus ditulis < img />
, dan tag ganda seperti < li > oranges
harus ditulis < li > oranges < / li >
.
Berikut adalah kode dan daftar tugas Putri dengan tag ganda:
<>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Putri"
class="photo"
/>
<ul>
<li>Mengerjakan PR</li>
<li>Pergi Belanja</li>
<li>Minum vitamin</li>
</ul>
</>
JSX berubah menjadi JavaScript dan atribut yang ditulis di JSX menjadi key pada objek di JavaScript. Dalam komponen, atribut akan lebih mudah dibaca sebagai variable. Namun JavaScript memiliki beberapa batasan dalam menamai variabel. Contohnya, nama variabel tidak boleh terdiri dari karakter minus dan tidak boleh menggunakan nama pesanan tertentu seperti class
.
Inilah mengapa di React, banyak atribut HTML dan SVG ditulis secara camelCase. Contohnya, stroke-width
dapat ditulis sebagai strokeWidth
. Dan karena class merupakan nama pesanan, di React kita menulisnya sebagai className
, dinamakan sesuai dengan versi DOM-nya:
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Putri"
className="photo"
/>
Anda dapat mencari semua atribut pada list DOM component berikut. Jika ada yang salah, jangan takut—React akan menampilkan pesan dengan koreksi ke konsol browser.
Mengubah atribut di markup yang sudah ada bisa menjadi membosankan. Disarankan untuk menggunakan converter untuk mengubah HTML dan SVG-mu menjadi JSX. Konverter sangat berguna dalam praktiknya, namun tetap ada baiknya Anda perlu memahami kodenya sehingga Anda dapat menulis JSX sendiri dengan nyaman.
Berikut hasil jadinya:
JSX memungkinkan Anda menulis markup mirip HTML di dalam file JavaScript, sehingga membuat logika rendering dan konten berada pada satu tempat yang sama. Terkadang Anda akan ingin menambahkan sedikit logika JavaScript atau merujuk pada properti yang dinamis di dalam markup tersebut. Dalam situasi ini, Anda dapat menggunakan tanda kurung kurawal pada JSX untuk membuka akses ke JavaScript.
Ketika Anda ingin oper atribut string ke JSX, Anda memasukkannya ke dalam tanda kutip tunggal atau ganda. Perhatikan kode berikut.
export default function Avatar() {
return (
<img
className="avatar"
src="https://i.imgur.com/7vQD0fPs.jpg"
alt="Gregorio Y. Zara"
/>
);
}
Di sini kode tersebut, "https://i.imgur.com/7vQD0fPs.jpg"
dan "Gregorio Y. Zara"
sedang dioper sebagai string.
Namun bagaimana jika Anda ingin secara dinamis menentukan teks src
atau alt
? Anda dapat menggunakan nilai dari JavaScript dengan mengganti kode seperti berikut:
export default function Avatar() {
const avatar = 'https://i.imgur.com/7vQD0fPs.jpg';
const description = 'Gregorio Y. Zara';
return (
<img
className="avatar"
src={avatar}
alt={description}
/>
);
}
Perhatikan perbedaan antara className="avatar"
, yang menentukan nama kelas CSS "avatar"
yang membuat gambar bulat, dan src={avatar}
yang membaca nilai variabel JavaScript disebut avatar. Hal itu terjadi karena kurung kurawal memungkinkan Anda bekerja dengan JavaScript langsung di markup Anda.
JSX merupakan cara khusus dalam menulis JavaScript. Artinya, memungkinkan untuk menggunakan JavaScript di dalamnya - dengan kurung kurawal { }
. Contohnya di bawah ini pertama perlu mendeklarasikan sebuah nama untuk ilmuwan, name, kemudian menyematkannya dengan kurung kurawal di dalam h1
:
export default function TodoList() {
const name = 'Gregorio Y. Zara';
return (
<h1>{name}'s To Do List</h1>
);
}
Sekarang kita ubah nilai name
dari 'Gregorio Y. Zara'
menjadi 'Hedy Lamarr'
. Lihat bagaimana judul daftar berubah?
Setiap ekspresi JavaScript akan berfungsi di antara kurung kurawal, termasuk fungsi seperti formatDate()
, perhatikan kode berikut:
const today = new Date();
function formatDate(date) {
return new Intl.DateTimeFormat(
'en-US',
{ weekday: 'long' }
).format(date);
}
export default function TodoList() {
return (
<h1>To Do List for {formatDate(today)}</h1>
);
}
Anda hanya dapat menggunakan kurung kurawal (curly braces) dalam dua cara di dalam JSX:
< h1 >Daftar Tugas {name} h1 >
berfungsi, tetapi < {tag} >Daftar Tugas Gregorio Y. Zara {tag} >
tidak akan berhasil.src={avatar}
akan membaca variabel avatar
, tetapi src="{avatar}"
akan mengoper sebagai string "{avatar}"
.Selain string, angka, dan ekspresi JavaScript lainnya, Anda bahkan dapat mengoper objek dalam JSX. Objek juga ditandai dengan kurung kurawal, seperti { name: "Hedy Lamarr", inventions: 5 }
. Oleh karena itu, untuk mengoper objek JavaScript di JSX, Anda harus membungkus objek tersebut dalam sepasang kurung kurawal lainnya seperti ini: person={{ name: "Hedy Lamarr", inventions: 5 }}
.
Anda mungkin melihat ini pada gaya CSS inline dalam JSX. React tidak mengharuskan Anda untuk menggunakan gaya inline (kelas CSS berfungsi lebih baik untuk kebanyakan kasus). Namun, ketika Anda membutuhkan gaya inline, Anda dapat mengoper objek ke atribut style
seperti kode berikut:
export default function TodoList() {
return (
<ul style={{
backgroundColor: 'black',
color: 'pink'
}}>
<li>Improve the videophone</li>
<li>Prepare aeronautics lectures</li>
<li>Work on the alcohol-fuelled engine</li>
</ul>
);
}
Sekarang kita ubah nilai dari backgroundColor
dan color
.
Anda dapat melihat objek JavaScript di dalam kurung kurawal dengan jelas ketika Anda menulisnya seperti ini:
<ul style={
{
backgroundColor: 'black',
color: 'pink'
}
}>
Ketika Anda melihat {{
dan }}
di dalam JSX, Anda akan tahu bahwa itu tidak lebih dari objek di dalam kurung kurawal JSX.
Anda dapat memasukkan beberapa ekspresi ke dalam satu objek, dan merujuk pada objek tersebut di dalam JSX menggunakan kurung kurawal. Sebagai contoh perhatikan kode berikut:
const person = {
name: 'Gregorio Y. Zara',
theme: {
backgroundColor: 'black',
color: 'pink'
}
};
export default function TodoList() {
return (
<div style={person.theme}>
<h1>{person.name}'s Todos</h1>
<img
className="avatar"
src="https://i.imgur.com/7vQD0fPs.jpg"
alt="Gregorio Y. Zara"
/>
<ul>
<li>Improve the videophone</li>
<li>Prepare aeronautics lectures</li>
<li>Work on the alcohol-fuelled engine</li>
</ul>
</div>
);
}
Pada contoh kode tersebut, objek JavaScript person
berisi sebuah string name
dan sebuah objek theme
:
const person = {
name: 'Gregorio Y. Zara',
theme: {
backgroundColor: 'black',
color: 'pink'
}
};
Komponen dapat menggunakan nilai-nilai dari objek person
seperti ini:
<div style={person.theme}>
<h1>{person.name}'s Todos</h1>
JSX sangat sederhana sebagai bahasa templating karena memungkinkan Anda untuk mengorganisir data dan logika menggunakan JavaScript.
Selesaikan langkah-langkah praktikum berikut ini menggunakan editor Visual Studio Code (VS Code) atau code editor lain kesukaan Anda. Jawablah di laporan praktikum Anda pada setiap soal yang ada di beberapa langkah praktikum ini.
Buatlah file baru di src/components/todolist.tsx
berisi kode seperti berikut:
const person = {
name: 'Gregorio Y. Zara',
theme: {
backgroundColor: 'black',
color: 'pink'
}
};
export default function TodoList() {
return (
<div style={person.theme}>
<h1>{person}'s Todos</h1>
<img
className="avatar"
src="https://i.imgur.com/7vQD0fPs.jpg"
alt="Gregorio Y. Zara"
/>
<ul>
<li>Improve the videophone</li>
<li>Prepare aeronautics lectures</li>
<li>Work on the alcohol-fuelled engine</li>
</ul>
</div>
);
}
Lakukan impor komponen di src/app/page.tsx
seperti berikut ini.
import { Gallery } from "@/components/gallery";
import TodoList from "@/components/todolist";
export default function Home() {
return (
<section>
<h1 className="font-semibold text-slate-900 truncate pr-20 text-center">Ilmuwan yang luar biasa</h1>
<hr />
<Gallery />
<hr />
<TodoList />
</section>
);
}
Tetap di file src/components/todolist.tsx
ubahlah objek person dan tambah variabel baseUrl seperti di bawah ini. URL lengkap gambar dibagi menjadi empat bagian: URL dasar, imageId
, imageSize
, dan ekstensi file.
Kita ingin URL gambar menggabungkan atribut-atribut ini bersama-sama: URL dasar (selalu 'https://i.imgur.com/'
), imageId ('7vQD0fP')
, imageSize ('s')
, dan ekstensi file (selalu '.jpg'
). Namun, ada yang salah dengan atribut src
.
Bisakah anda memperbaikinya?
const baseUrl = 'https://i.imgur.com/';
const person = {
name: 'Gregorio Y. Zara',
imageId: '7vQD0fP',
imageSize: 's',
theme: {
backgroundColor: 'black',
color: 'pink'
}
};
export default function TodoList() {
return (
<div style={person.theme}>
<h1>{person.name}'s Todos</h1>
<img
className="avatar"
src="{baseUrl}{person.imageId}{person.imageSize}.jpg"
alt={person.name}
/>
<ul>
<li>Improve the videophone</li>
<li>Prepare aeronautics lectures</li>
<li>Work on the alcohol-fuelled engine</li>
</ul>
</div>
);
}
Komponen React menggunakan props untuk berkomunikasi antara satu dengan yang lainnya. Setiap komponen induk bisa mengirim beberapa informasi pada komponen-komponen anaknya dengan memberikan mereka props. Props mungkin akan mengingatkan Anda dengan atribut HTML, namun Anda bisa mengirim nilai JavaScript apa pun melalui itu, termasuk objek, senarai, bahkan fungsi.
Props adalah informasi yang Anda kirimkan pada tag JSX. Sebagai contoh, className
, src
, alt
, width
, dan height
adalah beberapa contoh dari props yang bisa Anda kirimkan pada < img >
seperti kode berikut:
function Avatar() {
return (
<img
className="avatar"
src="https://i.imgur.com/1bX5QH6.jpg"
alt="Lin Lanying"
width={100}
height={100}
/>
);
}
export default function Profile() {
return (
<Avatar />
);
}
Props yang bisa dikirimkan pada tag < img >
sudah didefinisikan sebelumnya (ReactDOM menyesuaikan dengan standar HTML). Namun Anda bisa mengirimkan props apa pun pada komponen Anda sendiri, Misalnya < Avatar >
, untuk dikustomisasi.
Pada kode ini, komponen Profile
tidak mengirimkan props apa pun pada komponen anaknya, yaitu Avatar
:
export default function Profile() {
return (
<Avatar />
);
}
Anda bisa memberi komponen Avatar
beberapa props dalam dua langkah.
Pertama-tama, kirimkan beberapa props pada komponen Avatar
. Sebagai contoh, mari kirimkan dua props: person
(sebuah objek), dan size
(sebuah angka):
export default function Profile() {
return (
<Avatar
person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }}
size={100}
/>
);
}
Sekarang Anda bisa membaca props tersebut di dalam komponen Avatar
.
Anda bisa membaca props tersebut dengan mendaftarkan namanya yaitu person
, size
dengan cara dipisahkan dengan koma di dalam ({
dan })
langsung setelah function Avatar
. Hal ini memungkinkan Anda untuk menggunakannya di dalam kode Avatar
, sama halnya saat Anda menggunakan variabel.
function Avatar({ person, size }) {
// sekarang person dan size bisa Anda pakai di sini
}
Tambahkan beberapa logika pada Avatar
yang menggunakan props person
dan size
untuk di-render, dan selesai.
Sekarang Anda bisa membuat Avatar
untuk di-render dalam banyak cara dan dengan props yang berbeda.
import { getImageUrl } from './utils';
function Avatar({ person, size }) {
return (
<img
className="avatar"
src={getImageUrl(person)}
alt={person.name}
width={size}
height={size}
/>
);
}
export default function Profile() {
return (
<div>
<Avatar
size={100}
person={{
name: 'Katsuko Saruhashi',
imageId: 'YfeOqp2'
}}
/>
<Avatar
size={80}
person={{
name: 'Aklilu Lemma',
imageId: 'OKS67lh'
}}
/>
<Avatar
size={50}
person={{
name: 'Lin Lanying',
imageId: '1bX5QH6'
}}
/>
</div>
);
}
export function getImageUrl(person, size = 's') {
return (
'https://i.imgur.com/' +
person.imageId +
size +
'.jpg'
);
}
Hasilnya:
Props membuat Anda berpikir tentang komponen induk dan komponen anak secara terpisah. Sebagai contoh, Anda bisa mengubah props person
atau size
di dalam Profile
tanpa perlu memikirkan bagaimana Avatar
menggunakannya. Begitupun, Anda bisa mengubah bagaimana Avatar
menggunakan props tersebut, tanpa menghiraukan Profile
.
Anda bisa menganggap props seperti "kenop" yang bisa disesuaikan. Props berperan sama seperti arguments pada functions—Nyatanya, props adalah satu-satunya argument pada komponen Anda. Komponen fungsi React menerima satu argument, sebuah objek props.
function Avatar(props) {
let person = props.person;
let size = props.size;
// ...
}
Biasanya Anda tidak memerlukan objek props secara utuh, maka Anda dapat memecahnya menjadi props tersendiri.
Jangan melewatkan pasangan kurung kurawal {
dan }
di dalam tanda kurung (
dan )
saat menyatakan props sebagai parameter seperti kode ini:
function Avatar({ person, size }) {
// ...
}
Sintaksis ini disebut "destructuring" dan ini berfungsi untuk membaca properti dari parameter fungsi, maka sebaiknya tulis seperti berikut ini:
function Avatar(props) {
let person = props.person;
let size = props.size;
// ...
}
Jika Anda ingin memberi prop nilai bawaan untuk berjaga-jaga saat tidak ada nilai yang ditentukan, Anda bisa melakukannya dengan destructring lalu meletakkan =
dan nilai bawaannya tepat setelah parameter seperti kode berikut ini:
function Avatar({ person, size = 100 }) {
// ...
}
Sekarang, jika < Avatar person={...} / >
di-render tanpa menerima prop size
, size
akan bernilai 100
.
Nilai bawaan hanya akan terpakai jika prop size
tidak ada atau jika Anda mengirim size={undefined}
. Namun jika Anda mengirim size={null}
atau size={0}
, nilai bawaan tidak akan terpakai.
Terkadang, mengirim props bisa sangat repetitif:
function Profile({ person, size, isSepia, thickBorder }) {
return (
<div className="card">
<Avatar
person={person}
size={size}
isSepia={isSepia}
thickBorder={thickBorder}
/>
</div>
);
}
Tidak ada salahnya dengan kode yang repetitif—itu membuatnya lebih mudah untuk dibaca. Namun terkadang Anda mungkin lebih menyukai keringkasan. Beberapa komponen meneruskan semua propsnya kepada komponen anaknya, persis seperti yang Profile
lakukan dengan Avatar
. Karena mereka tidak menggunakan props-nya secara langsung, ini akan masuk akal untuk menggunakan sintaksis "spread" yang mana lebih ringkas seperti kode berikut:
function Profile(props) {
return (
<div className="card">
<Avatar {...props} />
</div>
);
}
Ini akan meneruskan semua props milik Profile
pada Avatar
tanpa menuliskannya satu-persatu.
Gunakan sintaksis spread dengan batasan. Jika Anda menggunakannya pada setiap komponen, maka akan ada yang salah. Seringkali, ini menunjukan bahwa Anda perlu memecah komponen Anda dan mengirim anaknya sebagai JSX. Mari kita bahas!
Sudah umum untuk menyisipkan tag bawaan pada browser:
<div>
<img />
</div>
Terkadang Anda ingin menyisipkan komponen Anda dengan cara yang sama:
<Card>
<Avatar />
</Card>
Saat Anda menyisipkan konten ke dalam tag JSX, komponen induk akan menerima konten tersebut dalam bentuk prop yang disebut children
. Sebagai contoh, Komponen Card
di bawah akan menerima prop children
yang diisi < Avatar / >
lalu me-rendernya dengan cara membungkusnya ke dalam div
:
import Avatar from './Avatar';
function Card({ children }) {
return (
<div className="card">
{children}
</div>
);
}
export default function Profile() {
return (
<Card>
<Avatar
size={100}
person={{
name: 'Katsuko Saruhashi',
imageId: 'YfeOqp2'
}}
/>
</Card>
);
}
Cobalah ubah < Avatar >
yang ada di dalam < Card >
dengan teks untuk melihat bagaimana komponen Card
bisa disisipkan konten apa pun. Komponen tersebut tidak perlu "mengetahui" apa yang di-render di dalamnya. Anda lihat betapa fleksibelnya hal ini.
Anda bisa menganggap bahwa komponen dengan prop children
itu mempunyai "lubang" yang bisa "diisi" oleh komponen induknya dengan JSX secara bebas. Anda akan sering menggunakan prop children
sebagai pembungkus: panels, grids, dan lainnya.
Komponen Clock
di bawah menerima dua props dari komponen induknya: color
dan time
. (Kode untuk komponen induknya dihilangkan karena itu menggunakan state, yang mana belum kita bahas untuk saat ini.)
export default function Clock({ color, time }) {
return (
<h1 style={{ color: color }}>
{time}
</h1>
);
}
Hasilnya:
Contoh ini menggambarkan bahwa sebuah komponen mungkin menerima props yang berbeda seiring waktu. Props tidak selalu bersifat tetap! Begini, prop time
berubah setiap detik, dan prop color
berubah ketika Anda memilih warna lain. Data pada komponen akan ditampilkan props kapan saja, bukan hanya di awal.
Bagaimanapun, props bersifat immutable—Sebuah istilah pada ilmu komputer yang berarti "tidak dapat diubah". Saat sebuah komponen ingin mengubah propsnya (sebagai contoh, untuk merespon interaksi pengguna atau merespon data baru), mereka harus "meminta" komponen induknya untuk mengirim dirinya props yang lain—objek baru! Lalu props yang lama akan disingkirkan, dan nantinya mesin JavasCript akan mengambil kembali memori yang dipakai oleh mereka.
Jangan mencoba untuk "mengubah props". Ketika Anda perlu merespon masukan pengguna (misalnya mengubah warna yang dipilih), Anda akan memerlukan "set state", yang mana akan Anda pelajari pada State: Memori Milik Komponen.
Selesaikan langkah-langkah praktikum berikut ini menggunakan editor Visual Studio Code (VS Code) atau code editor lain kesukaan Anda. Jawablah di laporan praktikum Anda pada setiap soal yang ada di beberapa langkah praktikum ini.
Buatlah file baru di src/components/mygallery.tsx
berisi kode seperti berikut:
import { getImageUrl } from '@/utils/utils';
export default function MyGallery() {
return (
<div>
<h1>Notable Scientists</h1>
<section className="profile">
<h2>Maria Skłodowska-Curie</h2>
<img
className="avatar"
src={getImageUrl('szV5sdG')}
alt="Maria Skłodowska-Curie"
width={70}
height={70}
/>
<ul>
<li>
<b>Profesi: </b>
Fisikawan dan kimiawan
</li>
<li>
<b>Penghargaan: 4 </b>
(Penghargaan Nobel Fisika, Penghargaan Nobel Kimia, Medali Davy, Medali Matteucci)
</li>
<li>
<b>Telah Menemukan: </b>
polonium (unsur kimia)
</li>
</ul>
</section>
<section className="profile">
<h2>Katsuko Saruhashi</h2>
<img
className="avatar"
src={getImageUrl('YfeOqp2')}
alt="Katsuko Saruhashi"
width={70}
height={70}
/>
<ul>
<li>
<b>Profesi: </b>
Ahli Geokimia
</li>
<li>
<b>Penghargaan: 2 </b>
(Penghargaan Miyake Geokimia, Penghargaan Tanaka)
</li>
<li>
<b>Telah Menemukan: </b>
sebuah metode untuk mengukur karbon dioksida pada air laut
</li>
</ul>
</section>
</div>
);
}
Buatlah file baru di src/utils/utils.tsx
berisi kode seperti berikut:
export function getImageUrl(imageId, size = 's') {
return (
'https://i.imgur.com/' +
imageId +
size +
'.jpg'
);
}
Buatlah file baru di src/components/myprofile.tsx
berisi kode seperti berikut:
import { getImageUrlV2 } from '@/utils/utils';
function MyAvatar({ person, size }) {
return (
<img
className="avatar"
src={getImageUrl(person, 'b')}
alt={person.name}
width={size}
height={size}
/>
);
}
export default function MyProfile() {
return (
<MyAvatar
size={40}
person={{
name: 'Gregorio Y. Zara',
imageId: '7vQD0fP'
}}
/>
);
}
Tambahkan fungsi getImageUrlV2
seperti berikut di file yang sama yaitu utils.tsx
src/utils/utils.tsx
export function getImageUrlV2(person, size) {
return (
'https://i.imgur.com/' +
person.imageId +
size +
'.jpg'
);
}
Pada contoh ini, komponen MyAvatar
menerima prop size
yang berupa angka dan akan digunakan untuk menentukan lebar dan tinggi < img >
. Prop size
dibuat 40
pada contoh ini. Bagaimanapun, jika Anda membuka gambar tersebut di web, Anda akan melihat bahwa gambarnya akan lebih besar (160
piksel). Ukuran gambar yang sebenarnya ditentukan oleh ukuran thumbnail yang Anda minta.
Buatlah file baru di src/components/myprofilev2.tsx
berisi kode seperti berikut:
export default function MyProfileV2() {
return (
<div>
<div className="card">
<div className="card-content">
<h1>Foto</h1>
<img
className="avatar"
src="https://i.imgur.com/OKS67lhm.jpg"
alt="Aklilu Lemma"
width={70}
height={70}
/>
</div>
</div>
<div className="card">
<div className="card-content">
<h1>Tentang</h1>
<p>Aklilu Lemma adalah seorang ilmuwan terkemuka dari etiopia yang telah menemukan pengobatan alami untuk skistosomiasis.</p>
</div>
</div>
</div>
);
}
Selamat, Anda telah berhasil menyelesaikan codelab ini. Beberapa konsep ReactJS yang lain akan dipelajari pada pertemuan berikutnya.
Silakan cek beberapa sumber belajar lainnya...