Contents
Pengantar React UI Component
Di modul sebelumnya, Anda telah belajar tentang konsep dasar yang ada di React. Anda sudah tahu bahwa React menganut konsep composition, declarative code, unidirectional data flow, dan React hanyalah JavaScript. Anda juga sudah mengenal secara singkat bahwa React element dan component adalah dua hal yang sering digunakan dalam membangun UI.
Modul ini akan membahas lebih dalam tentang element dan component di React dengan poin-poin seperti berikut.
- Membuat React element dan component pertama.
- Mengenal component properties.
- Komposisi component.
- Membuat aplikasi menggunakan React berdasarkan studi kasus “Aplikasi Buku Kontak”.
Bersiaplah! Materi di modul ini akan terasa lebih panjang. Siapkan jari jemari Anda untuk mulai menuliskan kode ya! Jika sudah tidak sabar, Anda bisa menekan tombol selanjutnya.
React Starter pada Online Code Editor
Kami akan banyak menunjukkan kode yang bekerja pada React untuk beberapa materi berikutnya. Sayangnya, saat ini Anda tidak bisa mempraktikkanya langsung pada browser karena untuk menjalankan kode React butuh memasang beberapa package JavaScript terlebih dulu. Di modul sebelumnya, kami menyinggung bahwa pembuatan proyek React tidaklah sederhana dan tidak cocok untuk dipelajari di awal.
Sebagai solusinya, kami telah menyiapkan sebuah proyek lengkap dengan seluruh persiapan dan kebutuhan dalam menggunakan React. Proyek tersebut kami simpan di CodeSandbox (code editor online) dan dapat Anda akses pada tautan: dicoding-react-starter.
Manfaatkan proyek tersebut setiap kali ingin mempraktikkan kode React sehingga Anda tidak perlu repot menyiapkan proyek secara lokal. Cukup tulis kode React pada bilah editor dan hasilnya pun akan muncul secara instan.
CodeSandbox cukup terkenal dan mungkin saja Anda sudah pernah menggunakannya. Ia memiliki fitur dan tampilan yang bisa dikatakan sama seperti code editor pada umumnya. Jika Anda terbiasa dengan code editor seperti VSCode, seharusnya penggunaan CodeSandbox tidak jauh berbeda.
Tips Penggunaan CodeSandbox
Ada beberapa tips terkait penggunaan CodeSandbox yang memudahkan Anda untuk mengikuti materi di kelas ini.
- Silakan bookmark (tandai sebagai favorit) tautan dicoding-react-starter agar lebih mudah untuk diakses secara berkala.
- Buatlah akun CodeSandbox agar kode yang Anda tulis tersimpan. Anda bisa membuat akun secara cepat dengan memanfaatkan OAuth seperti Google Account atau GitHub.
- Manfaatkan fitur console yang berada di panel bawah kanan untuk melihat nilai yang dicetak oleh console (seperti console.log).
-
Jika ingin lebih leluasa dalam men-debug web, manfaatkanlah fitur Open In New Tab (lihat tanda kotak merah di bawah) untuk membuka halaman web secara penuh pada tab browser yang berbeda.
Dengan begitu, Anda bisa memanfaatkan Inspect Element atau fitur debugging lainnya yang berada di developer tools browser.
Catatan: Penggunaan platform CodeSandbox hanyalah sementara. Bila Anda sudah belajar bagaimana membuat proyek React secara lokal, Anda bisa mempraktikkan kode React langsung tanpa bantuan code editor online. Harap bersabar ya, cara menyiapkan proyek React akan dibahas di beberapa materi ke depan.
React Element
Seluruh antarmuka pengguna (UI) aplikasi React dibangun menggunakan React element. Sama seperti DOM element, React element dapat berupa paragraf, heading, atau gambar. React element merepresentasikan apa yang Anda lihat di layar.
Walaupun serupa dengan DOM element, React element dan DOM element browser tidaklah identik. React element hanyalah objek JavaScript polos, ringan, dan sangat mudah untuk dibuat. Cara paling sederhana dalam membuat React element adalah menggunakan fungsi berikut.
React.createElement(/* type */, /* property */, /* content */);
Fungsi createElement menerima 3 parameter, seperti:
- type yang merupakan tipe elemen,
- property merupakan properti dari elemen, dan
- content merupakan konten dari elemen.
Fungsi createElement mengembalikan React element sesuai dengan tipe yang ditetapkan pada parameter. Contoh, bila Anda ingin membuat elemen paragraf “Hello React”, gunakanlah fungsi createElement seperti ini.
const element = React.createElement('p', null, 'Hello, React!');
Jika Anda telaah nilai kembaliannya (element), React element hanyalah objek JavaScript biasa.
{ type: 'p', props: { children: 'Hello, React!', }, }
Nilai dari parameter type mendeskripsikan tipe dari React elemen yang akan dikembalikan. React menggunakan referensi HTML tags untuk menentukan tipe elemen. Jadi, nilai p berarti paragraf, h1 berarti heading tingkat 1, img berati gambar, dan seterusnya.
Lalu, bagaimana bila kita ingin menetapkan properti pada elemen? Pertanyaan bagus! Untuk melakukannya, Anda bisa memanfaatkan parameter kedua (property) dengan memberikan nilai berupa objek yang mendeskripsikan properti elemen yang ingin ditetapkan beserta nilainya. Contoh, bila Anda ingin menetapkan nilai pada properti className atau id, lakukanlah dengan cara seperti di bawah ini.
const element = React.createElement( 'p', { id: 'myParagraph', className: 'red-paragraph' }, 'Hello, React!' );
Catatan: React menggunakan Element Properties dalam menetapkan properti pada React element. Itulah mengapa dalam menetapkan class, kita menggunakan className dibandingkan dengan class. Penting untuk Anda ingat bahwa Element Properties dengan HTML Attribute itu berbeda meskipun beberapa nilai properti merepresentasikan nilai dari HTML atribut. React selalu menggunakan Element Properties sebagai referensi.
Nested React Element
Nilai children pada React element dapat diisi dengan tipe data apa pun, termasuk React element lain. Hal ini sangat wajar dan sering digunakan untuk membangun elemen secara nested.
Jika Anda sudah terbiasa membuat web, tentu Anda sering membuat struktur HTML nested seperti mengelompokkan beberapa element di dalam div.
<div class="container"> <h1>React</h1> <p>The <strong>best tool</strong> for building UI</p> </div>
Ketika menggunakan React, praktik tersebut lazim dan dapat dibuat dengan cara menetapkan nilai parameter child secara nested. Jika child memiliki lebih dari satu nilai, Anda bisa mengelompokkan nilainya di dalam array.
const heading = React.createElement('h1', null, 'React'); const strong = React.createElement('strong', null, 'best tool'); const paragraph = React.createElement('p', null, ['The ', strong, ' for building UI']) const divContainer = React.createElement('div', { className: 'container' }, [heading, paragraph]);
Lihat cara kami menetapkan children untuk elemen paragraph dan divContainer pada kode di atas! Anda bisa lihat bahwa nilai children merupakan array yang berisi beberapa nilai termasuk React element.
Latihan Membuat React Element
Setelah memahami semua teori yang ada mengenai React element, mari praktikkan supaya teori tersebut bisa melekat sempurna di benak Anda. Pada latihan kali ini, kita akan belajar membuat React element menggunakan fungsi createElement--yang sudah Anda ketahui sebelumnya--untuk membangun dan menampilkan UI sederhana pada browser.
Jangan berekspektasi terlalu tinggi dulu ya! Kita akan mulai dengan hal yang sederhana yaitu membuat UI “Biodata Perusahaan”. Berikut tampilan hasilnya.
Berikut tujuan dari latihan kali ini.
- Mampu membuat React element sederhana.
- Mampu membuat React element yang nested.
- Menginspeksi nilai React element dan mengetahui bahwa element hanyalah objek JavaScript.
- Menampilkan React element pada halaman web dengan bantuan react-dom.
-
Pertama, bukalah tautan dicoding-react-starter karena kita akan menuliskan seluruh kode di sana.
-
Agar kita dapat menuliskan sintaksis React.createElement, silakan impor module react yang sudah kami siapkan (lihat pada bagian dependencies) menggunakan perintah berikut.
Perlu kalian ingat juga bahwa pada proyek yang kami siapkan, Anda bisa melakukan modularization (modularisasi). Pastikan juga Anda menggunakan format ESM ketika mengimpor atau mengekspor sebuah modul. Jika Anda belum familier dengan teknik modularisasi menggunakan ESM, kami sarankan untuk mempelajarinya terlebih dahulu. Setelah mengimpor module react, sekarang Anda bisa menggunakan seluruh sintaksis React melalui React.*.
import React from 'react';
-
Kita akan mulai membuat bagian heading terlebih dulu. Silakan tuliskan kode berikut.
Kode di atas berarti kita membuat sebuah React element dengan type h1 dan child (kontennya) bernilai teks “Biodata Perusahaan”. Dari teori yang sudah Anda ketahui, React element hanyalah sebatas objek JavaScript biasa. Anda bisa melihat “jati diri” yang sebenarnya menggunakan console.log seperti ini.
import React from 'react'; const heading = React.createElement('h1', null, 'Biodata Perusahaan');
Silakan lihat output dari console.log pada bilah console yang disediakan CodeSandBox.import React from 'react'; const heading = React.createElement('h1', null, 'Biodata Perusahaan'); console.log(heading);
Gambar di atas menunjukkan bahwa React element hanyalah objek JavaScript biasa. Seluruh informasi yang dibutuhkan untuk ditampilkan dalam bentuk UI ada di objek tersebut, seperti elemen, properti, dan kontennya. Sebelum lanjut ke langkah berikutnya, kami sangat menyarankan Anda untuk melakukan eksplorasi mandiri, seperti memberikan properti id atau className pada element heading. Jangan lupa untuk melihat kembali output yang ditampilkan di console untuk mengetahui bagaimana properti id atau className dimuat pada objek JavaScript. Setelah Anda puas bereksplorasi, silakan hapus kembali kode console.log(heading); karena sebenarnya kode tersebut hanya digunakan bila Anda ingin menginspeksi suatu nilai pada console. -
Selanjutnya kita akan menampilkan elemen heading yang sudah kita buat pada browser. Langkah ini menjadi moment of truth bahwa React element yang sejatinya hanya JavaScript objek--di mana ukurannya sangat kecil--ternyata bisa diubah menjadi DOM element untuk ditampilkan pada Browser.
Untuk menampilkan React element pada Browser, kita perlu membuat root yang nantinya digunakan sebagai penampung di mana React element akan di-render. Untuk membuat root, gunakan fungsi createRoot yang tersedia pada module react-dom/client.
Silakan impor fungsi createRoot menggunakan kode berikut.
Catatan: Semenjak React versi 18 untuk me-render di sisi client (browser), React menggunakan module ‘react-dom/client’ bukan lagi ‘react-dom’. Fungsi createRoot menerima satu parameter berupa HTML element yang menjadi referensi dari tempat di mana React element ditampung. Fungsi createRoot akan mengembalikan instance dari ReactDOMRoot yang bisa kita manfaatkan untuk me-render React element. Silakan tulis kode berikut untuk membuat root.
import React from 'react'; import { createRoot } from 'react-dom/client'; const heading = React.createElement('h1', null, 'Biodata Perusahaan');
Setelah membuat root, Anda bisa me-render React element dengan perintah root.render()seperti ini.import React from 'react'; import { createRoot } from 'react-dom/client'; const heading = React.createElement('h1', null, 'Biodata Perusahaan'); const root = createRoot(document.getElementById('root'));
Simpan perubahan dan React element pertama yang Anda buat akan muncul pada Browser CodeSandbox.import React from 'react'; import { createRoot } from 'react-dom/client'; const heading = React.createElement('h1', null, 'Biodata Perusahaan'); const root = createRoot(document.getElementById('root')); root.render(heading);
Oke dari kode di atas, mungkin Anda bertanya-tanya dari mana HTML element yang kami gunakan untuk membuat root? Jawabannya adalah element tersebut sudah kami siapkan dan Anda bisa melihatnya pada berkas public -> index.html.
Di dalam elemen div#root tersebut, semua React element yang di-render akan diletakkan. Untuk membuktikannya, silakan inspect halaman browser yang menampilkan aplikasi React dan lihat bahwa element root menjadi penampung dari element React.
Untuk melakukan inspeksi menggunakan Browser Developer Tools, kami sarankan manfaatkan fitur Open In New Tab yang disediakan oleh CodeSandBox. Jika sudah paham, kita lanjutkan langkahnya ya. -
Mari kita buat React element lain. Sekarang, buatlah 3 React element baru untuk menampung informasi list item nama, bidang, dan tagline dari perusahaan. Karena ini merupakan list item, pastikan Anda menggunakan li sebagai tipe elemennya.
import React from 'react'; import { createRoot } from 'react-dom/client'; const heading = React.createElement('h1', null, 'Biodata Perusahaan'); const listItem1 = React.createElement('li', null, 'Nama: Dicoding Indonesia'); const listItem2 = React.createElement('li', null, 'Bidang: Education'); const listItem3 = React.createElement('li', null, 'Tagline: Decode Ideas, Discover Potential.'); const root = createRoot(document.getElementById('root')); root.render(heading);
-
Selanjutnya, buat juga React element baru yang berfungsi sebagai unordered list dari setiap list item yang sudah kita buat.
import React from 'react'; import { createRoot } from 'react-dom/client'; const heading = React.createElement('h1', null, 'Biodata Perusahaan'); const listItem1 = React.createElement('li', null, 'Nama: Dicoding Indonesia'); const listItem2 = React.createElement('li', null, 'Bidang: Education'); const listItem3 = React.createElement('li', null, 'Tagline: Decode Ideas, Discover Potential.'); const unorderedList = React.createElement('ul', null, [listItem1, listItem2, listItem3]); const root = createRoot(document.getElementById('root')); root.render(heading);
Lihatlah kode dalam pembuatan element unorderedList, di sana kita membuat React element yang nested, alias menampung banyak element lain di dalamnya. Karena itu, nilai child yang kita berikan di sana merupakan array dari React element.
-
Element terakhir yang akan kita buat adalah container. Element ini berfungsi sebagai parent container alias penampung seluruh React element yang akan ditampilkan pada browser. Kita butuh element container karena fungsi root.render hanya menerima satu React element untuk di-render dan element container inilah yang akan di-render.
Silakan buat element container bertipe div, lalu buat element heading dan unorderedList sebagai nilai child-nya.
import React from 'react'; import { createRoot } from 'react-dom/client'; const heading = React.createElement('h1', null, 'Biodata Perusahaan'); const listItem1 = React.createElement('li', null, 'Nama: Dicoding Indonesia'); const listItem2 = React.createElement('li', null, 'Bidang: Education'); const listItem3 = React.createElement('li', null, 'Tagline: Decode Ideas, Discover Potential.'); const unorderedList = React.createElement('ul', null, [listItem1, listItem2, listItem3]); const container = React.createElement('div', null, [heading, unorderedList]); const root = createRoot(document.getElementById('root')); root.render(heading);
-
Terakhir, ubahlah elemen yang di-render oleh root.render dari headingmenjadi container.
import React from 'react'; import { createRoot } from 'react-dom/client'; const heading = React.createElement('h1', null, 'Biodata Perusahaan'); const listItem1 = React.createElement('li', null, 'Nama: Dicoding Indonesia'); const listItem2 = React.createElement('li', null, 'Bidang: Education'); const listItem3 = React.createElement('li', null, 'Tagline: Decode Ideas, Discover Potential.'); const unorderedList = React.createElement('ul', null, [listItem1, listItem2, listItem3]); const container = React.createElement('div', null, [heading, unorderedList]); const root = createRoot(document.getElementById('root')); root.render(container);
Simpan perubahannya dan kini Browser CodeSandBox akan menampilkan UI seperti ini.
Lakukan inspeksi kembali pada halaman browser untuk melihat seperti apa struktur HTML yang di-render oleh root. Simak juga bagaimana root me-render React element menjadi struktur HTML yang sudah umum Anda lakukan sebagai web developer secara native.
Well done! Anda sudah berhasil membuat React element dan menampilkannya pada Browser dengan bantuan ReactDOM. Ini hanyalah langkah awal, modul selanjutnya akan lebih seru dan membuat Anda lebih jatuh cinta terhadap React.
JSX
“Kok membuat React elemen lebih sulit ya dibandingkan membuat HTML biasa?” - Anda mungkin berpikir demikian setelah melihat kode yang ada di materi Nested React Element yang kami berikan. Yup! Memang tidak salah. Membuat React element terasa sulit bila menggunakan fungsi createElement, terlebih bila elemen yang kita buat nested seperti contoh sebelumnya. React sendiri menganut konsep deklaratif, tetapi penggunaan createElement terasa sangat imperatif, hampir tak ada bedanya dengan fungsi standar document.createElement.
Tenang, React punya solusinya. Selain menggunakan fungsi createElement, Anda juga bisa membuat element dengan sintaksis JSX. Dengan JSX, pembuatan elemen jauh lebih mudah dan bersifat deklaratif.
Berikut adalah contoh dari sintaksis JSX:
const element = <p>Hello, React!</p>;
Sintaksis “unik” di atas bukanlah string ataupun HTML. Sintaksis tersebut dinamakan JSX karena extensions (penambahan) dari kemampuan standar JavaScript yang diberikan oleh React. Intinya, ketika menggunakan React, Anda bisa menuliskan sintaksis unik tersebut di JavaScript.
Sintaksis JSX mengembalikan React element sesuai dengan yang Anda deklarasikan. Sintaksis JSX mirip seperti HTML karena memanfaatkan tag--khas gaya markup--dalam mendeklarasikan elemen. Dengan menggunakan JSX, Anda bisa terbebas dari penggunakan fungsi createElement dalam membuat element.
// JSX const element = <p className="red-paragraph">Hello, React!</p>;
// createElement const element = React.createElement( 'p', { className: 'red-paragraph', }, 'Hello, React!', );
Catatan: Properti elemen pada JSX dituliskan mirip atribut pada HTML. Namun, referensinya tetap mengacu pada standar Element Properties, bukan HTML Attributes.
Kami bilang JSX mirip HTML bukan berarti keduanya adalah sama. Perbedaannya adalah di JSX, Anda bisa menuliskan JavaScript expression ketika membuat elemen. Karena JSX memang dituliskan pada lingkup JavaScript. Caranya, tuliskan expression di antara tanda kurung kurawal { }.
Berikut contoh penulisan expression di JSX.
const name = 'Dicoding'; const element = <p>Hello, {name}</p>;
Variabel element akan bernilai:
{ type: 'p', props: { children: ['Hello, ', 'Dicoding'] } }
Terakhir, JSX menyapu kerumitan pembuatan nested element yang dilakukan dengan fungsi createElement. Pasalnya, dengan gaya deklaratif yang ia miliki, kita bisa lebih mudah melakukan nested element layaknya menuliskan sintaksis HTML biasa.
Lihat perbedaan antara JSX dan createElement.
// JSX const divContainer = ( <div className="container"> <h1>React</h1> <p>The <strong>best tool</strong> for building UI</p> </div> );
// createElement const heading = React.createElement('h1', null, 'React'); const strong = React.createElement('strong', null, 'best tool'); const paragraph = React.createElement('p', null, ['The ', strong, ' for building UI']) const divContainer = React.createElement('div', { className: 'container' }, [heading, paragraph]);
Catatan: Penggunaan tanda kurung () yang menghimpit sintaksis JSX tidak berarti apa-apa. Hal itu hanyalah convention ketika Anda menuliskan sintaksis JSX pada baris baru. Tujuannya, agar sintaksis JSX lebih rapi dan mudah dibaca.
JSX hanya mengembalikan satu element
Ketika menuliskan JSX, pastikan ia hanya mengembalikan satu elemen. Meskipun React element bisa nested, tapi pastikan hanya ada satu root element yang membungkus seluruh element di dalamnya.
const element = ( <div className="container"> <h1>React</h1> <p>The <strong>best tool</strong> for building UI</p> </div> );
Lihat kode JSX di atas! Ia hanya mengembalikan satu root elemen yaitu <div>, walaupun di dalamnya kami menuliskan lebih dari satu elemen. Inilah cara yang benar jika Anda ingin membuat banyak element menggunakan JSX. Agar lebih jelas lagi, berikut adalah contoh praktik yang salah dalam penggunaan JSX.
const element = ( <h1>React</h1> <p>The <strong>best tool</strong> for building UI</p> );
Pada contoh di atas, kami menuliskan dua root element yaitu <h1> dan <p>. Sintaksis JSX seperti ini tidak benar dan dianggap sebagai syntax error.
Karena Anda sudah mengetahui penggunaan fungsi createElement() maka aturan ini tentu masuk akal. Karena fungsi createElement() pun hanya menerima satu tag (dalam bentuk string) pada parameter pertama.
Bahan bacaan lebih lanjut.
Latihan Menggunakan JSX
Pada latihan sebelumnya, Anda sudah berhasil membangun UI sederhana menggunakan React element melalui fungsi createElement(). Anda pasti setuju bahwa pembuatan element menggunakan fungsi tersebut ternyata sulit dan membuat pusing bila kita perlu membangun UI yang kompleks. Maka dari itu, hadirlah JSX guna meringankan beban tersebut.
Secara teori, Anda sudah mengetahui JSX, tetapi kurang afdal rasanya bila belum mempraktikkannya langsung. Pada latihan kali ini, kita akan membuat dan menampilkan React element yang dibangun menggunakan JSX. Tujuan dari latihan ini tak lain agar Anda terbiasa dengan penggunaan sintaksis JSX.
Agar dapat membandingkan pengalaman dari penggunaan createElement dan JSX, kita akan membuat UI yang sama seperti latihan sebelumnya. Masih ingat kan tampilannya? Kurang lebih terlihat seperti berikut.
-
Pertama, buka kembali tautan dicoding-react-starter karena kita akan menuliskan seluruh kode di sana.
-
Sama seperti sebelumnya, kita perlu mengimpor module react dan react-domagar dapat menuliskan sintaksis React di JavaScript.
import React from 'react'; import { createRoot } from 'react-dom/client';
Catatan: Meskipun dengan JSX, kita tidak perlu menggunakan keyword React ketika menggunakannya, tetapi tetap lakukan impor module React. Hal ini untuk menghindari “kemungkinan” eror yang terjadi ketika Babel hendak mengubah kode JSX menjadi kode JavaScript (biasanya eror terjadi pada React versi 16 ke bawah).
-
Selanjutnya buatlah React element menggunakan JSX sesuai UI yang kita kehendaki di atas.
import React from 'react'; import { createRoot } from 'react-dom/client'; const element = ( <div> <h1>Biodata Perusahaan</h1> <ul> <li>Nama: Dicoding Indonesia</li> <li>Bidang: Education</li> <li>Tagline: Decode Ideas, Discover Potential.</li> </ul> </div> );
Sekali lagi kami sampaikan bahwa sintaksis JSX mirip seperti HTML. Saking miripnya, Anda pun bisa memberikan properti pada React element sama halnya dengan memberikan atribut pada HTML. Bila Anda sudah terbiasa membangun aplikasi web dan menuliskan banyak sintaks HTML, seharusnya Anda sudah familier sehingga kami tidak perlu menjelaskan banyak hal terkait sintaksis JSX.
-
Selanjutnya agar React element terlihat di browser, kita perlu membuat root dan me-render element tersebut.
import React from 'react'; import { createRoot } from 'react-dom/client'; const element = ( <div> <h1>Biodata Perusahaan</h1> <ul> <li>Nama: Dicoding Indonesia</li> <li>Bidang: Education</li> <li>Tagline: Decode Ideas, Discover Potential.</li> </ul> </div> ); const root = createRoot(document.getElementById('root')); root.render(element);
Kini, UI--yang sama dengan latihan sebelumnya--akan tampak pada Browser CodeSandBox.
Di tahap ini, pasti Anda sudah merasakan bahwa menggunakan JSX jauh lebih mudah dan cepat dalam membuat UI ‘kan? Benar! Karena JSX bersifat deklaratif--sama seperti HTML--sehingga sintaksisnya jauh lebih mudah dibaca.
-
Selanjutnya, mari kita tambahkan elemen baru berupa gambar yang menampilkan logo perusahaan. Kita akan meletakkan element tersebut di paling bawah atau setelah list item informasi perusahaan. Silakan unduh logo Dicoding pada tautan berikut: dicoding-logo.png.
Sebelum menampilkan gambarnya, kami ingin beritahu bahwa React dapat menggunakan dua cara dalam menampilkan gambar.
Cara pertama adalah menuliskan URL gambar pada properti src dari element
. URL gambar dapat diambil dari internet ataupun berkas lokal yang disimpan pada folder public. Silakan unggah logo Dicoding dan simpan di dalam folder public yang ada pada proyek starter yang kami sediakan. Anda bisa mengunggah berkas dengan cara drag and drop.
Catatan: Pastikan Anda sudah membuat akun CodeSandBox dan login agar dapat mengunggah berkas pada proyek.
Setelah itu, Anda bisa menampilkan gambarnya menggunakan <img>seperti ini
import React from 'react'; import { createRoot } from 'react-dom/client'; const element = ( <div> <h1>Biodata Perusahaan</h1> <ul> <li>Nama: Dicoding Indonesia</li> <li>Bidang: Education</li> <li>Tagline: Decode Ideas, Discover Potential.</li> <img src="dicoding-logo.png" alt="Dicoding logo" /> </ul> </div> ); const root = createRoot(document.getElementById('root')); root.render(element);
Simpan perubahan kodenya dan sekarang gambar akan muncul pada Browser CodeSandBox.
Catatan: Bila gambar belum muncul atau gagal dimunculkan, silakan reload Browser CodeSandBox dengan menekan tombol Reload yang berada di samping address bar.
Mudah ‘kan? Yang perlu Anda ingat adalah seluruh berkas yang berada di folder public bersifat publik dan dapat diakses melalui URL aplikasi. Itulah mengapa index.html dapat diakses melalui URL.
Cara kedua yaitu menggunakan teknik modularisasi. Modularisasi? Yup, Anda tidak salah membacanya. Jadi, proyek React--yang menggunakan webpack--dapat memperlakukan berkas statis (seperti gambar, css, dan lainnya) layaknya module JavaScript. Dengan begitu, teknik kedua ini jelas dilakukan menggunakan kata kunci import.
Untuk mencobanya, pindahkan dulu (drag and drop) berkas dicoding-logo.png ke dalam folder src.
Kemudian impor gambar dicoding-logo.png sebagai module menggunakan kode berikut.
import React from 'react'; import { createRoot } from 'react-dom/client'; import DicodingLogo from './dicoding-logo.png'; // kode lain disembunyikan
Selanjutnya ubah nilai properti src dengan nilai DicodingLogo.
import React from 'react'; import { createRoot } from 'react-dom/client'; import DicodingLogo from './dicoding-logo.png'; const element = ( <div> <h1>Biodata Perusahaan</h1> <ul> <li>Nama: Dicoding Indonesia</li> <li>Bidang: Education</li> <li>Tagline: Decode Ideas, Discover Potential.</li> <img src={DicodingLogo} alt="Dicoding logo" /> </ul> </div> ); const root = createRoot(document.getElementById('root')); root.render(element);
Catatan: Ingat! JavaScript expression pada JSX selalu dibungkus di dalam tanda kurung kurawal { }.
Simpan perubahan dan lihat logo Dicoding tetap tampil pada Browser.
-
Terakhir, Anda juga bisa melakukan inspeksi terhadap tampilan web untuk melihat struktur HTML yang digunakan React dalam menampilkan gambar.
Di tahap ini, kami sangat merekomendasikan Anda untuk melakukan eksplorasi mandiri seperti menambahkan properti pada JSX element atau bermain-main dengan membangun UI lain yang menurut Anda lebih menantang.
React Component
Sejauh ini, kita telah mengetahui bagaimana .createElement() dan JSX dapat membantu kita dalam membuat React element yang ditampilkan pada Browser dengan bantuan React DOM. Selain React element, fitur utama lainnya yang sangat membantu kita dalam membangun UI adalah React Component. Fitur ini adalah kunci jika Anda ingin membangun UI yang reusable dan terisolasi.
Mudahnya, React component merupakan fungsi JavaScript yang mengembalikan React element. Alasan mengapa kita membuat React component sama dengan kapan kita harus membuat sebuah fungsi. Namun, alih-alih mengembalikan data, React component mengembalikan UI dalam bentuk React element.
Terdapat 2 alasan mengapa Anda perlu membuat component.
- Pembuatan UI (React element) membutuhkan logika yang tidak sederhana, serta Anda ingin proses pembuatan UI tersebut terisolasi. Dengan begitu, kode dalam membuat UI tersebut tidak mengganggu kode lainnya.
- Anda ingin membuat UI yang bersifat reusable. Artinya, hanya dengan satu kode UI namun dapat digunakan sebanyak apa pun dengan banyak varian data.
Konsep component sangat ciamik karena kita dapat memecah (break down) UI ke bagian-bagian kecil. Bagian-bagian kecil dari UI tersebut memiliki tanggung jawab yang jelas dan properti yang sudah terdefinisikan. Hal ini sangat penting ketika membangun aplikasi yang besar karena kita dapat bekerja fokus pada bagian terkecil dari aplikasi tanpa mengganggu keseluruhan kode yang ada.
Cara paling sederhana dalam membuat React component adalah menulis fungsi yang mengembalikan React element (dapat menggunakan JSX atau createElement).
function SayHello() { // Sebelum mengembalikan React element, Anda bisa menuliskan banyak kode JavaScript di sini. // Biasanya kode yang dituliskan seputar persiapan data untuk ditampilkan pada React element. return <p>Hello, World!</p> }
Catatan: Konvensi dalam penamaan React component selalu diawali dengan huruf besar. Hal ini bertujuan agar dapat membedakan antara built-in HTML element dan component yang Anda (atau pihak lain) buat sendiri.
React component dapat digunakan dengan cara yang berbeda dari fungsi biasa, yakni menggunakan sintaksis JSX seperti ini.
<SayHello /> // akan menampilkan ui <p>Hello, World!</p>
Layaknya sebuah fungsi, ia dapat digunakan sebanyak yang Anda mau.
<SayHello /> // akan menampilkan ui <p>Hello, World!</p> <SayHello /> // akan menampilkan ui <p>Hello, World!</p> <SayHello /> // akan menampilkan ui <p>Hello, World!</p> <SayHello /> // akan menampilkan ui <p>Hello, World!</p>
Perlu kalian ingat! Meskipun React component adalah fungsi JavaScript, tetapi ia harus diperlakukan (digunakan) layaknya sebuah component. Sebuah fungsi yang mengembalikan React element belum bisa dikatakan component bila Anda memanggilnya seperti ini.
SayHello(); // wrong practice!!
Component Properties
Karena React component merupakan fungsi JavaScript, kita dapat memberikan parameter ketika menggunakannya. Namun, React component hanya dapat menerima satu parameter--berupa objek--yang biasa kita sebut dengan properties (props).
// SayHello Component function SayHello(props) { const name = props.name; const company = props.company; return ( <p> Hello, {name} from {company}! </p> ); }
// Penggunaannya <SayHello name="Bill" company="Microsoft" />; // <p>Hello, Bill from Microsoft!</p> <SayHello name="Steve" company="Apple" />; // <p>Hello, Steve from Apple!</p> <SayHello name="Mark" company="Facebook" />; // <p>Hello, Mark from Facebook!</p>
Melalui props yang ditunjukkan kode di atas, kita dapat mengirimkan data ketika menggunakannya. Hal inilah yang membuat component sangat reusable karena hanya dengan satu component--beserta properti yang terdefinisikan--kita dapat menampilkan UI serupa dengan data yang berbeda.
Beberapa Best Practice ketika membuat dan menggunakan property
Hampir seluruh tipe data di JavaScript dapat dikirimkan melalui props. Namun, terdapat best practice dalam menetapkan properti yang penting untuk Anda ikuti.
Best practice yang pertama adalah hindari penggunaan JavaScript object ketika mengirimkan data pada properti component.
Contohnya seperti ini:
function InstagramProfile(props) { const profile = props.profile; const name = profile.name; const username = profile.username; const bio = profile.bio; const isVerified = profile.isVerified; return ( <div className="container"> <dl> <dt>Name: </dt> <dd>{name}</dd> <dt>Username: </dt> <dd>{username}</dd> <dt>Bio: </dt> <dd>{bio}</dd> <dt>Verified: </dt> <dd>{isVerified ? 'yes' : 'no'}</dd> </dl> </div> ); } const profile = { name: 'Dicoding Indonesia', username: 'dicoding', bio: 'Bangun Karirmu Sebagai Developer Profesional', isVerified: true }; <InstagramProfile profile={profile} />; // sebisa mungkin, hindari praktik seperti ini
Oke, mungkin menggunakan objek sebagai “pembungkus” data terlihat lebih mudah karena kita hanya perlu mendefinisikan satu properti saja pada component yaitu profile. Namun, hal ini lah yang menyebabkan kontrak dalam penggunaan component tersebut tidak jelas. Sebab JavaScript merupakan bahasa yang tidak terikat dengan tipe data (weakly typed) sehingga praktik seperti ini sebaiknya dihindari.
Alih-alih mengirimkan props dalam bentuk objek, sebaiknya definisikanlah propertinya satu per satu. Sehingga, kita tak lagi mengirimkan objek, melainkan cukup dengan nilai primitif seperti string, number, atau boolean.
function InstagramProfile(props) { const name = props.name; const username = props.username; const bio = props.bio; const isVerified = props.isVerified; return ( <div className="container"> <dl> <dt>Name: </dt> <dd>{name}</dd> <dt>Username: </dt> <dd>{username}</dd> <dt>Bio: </dt> <dd>{bio}</dd> <dt>Verified: </dt> <dd>{isVerified ? 'yes' : 'no'}</dd> </dl> </div> ); } <InstagramProfile name="Dicoding Indonesia" username="dicoding" bio="Bangun Karirmu Sebagai Developer Profesional" isVerified // pemberian nilai boolean "true" cukup dengan menuliskan nama properti tanpa nilai apa pun />;
Dengan cara ini, kontrak dalam menggunakan component akan lebih terlihat lebih jelas. Selain itu, secara tidak langsung kita juga sudah menerapkan prinsip least privilege guna menghindari dalam mengirimkan data yang sebenarnya tidak diperlukan.
Best practice lainnya adalah selalu gunakan fitur ES6 agar sintaksis yang dituliskan lebih bersih, singkat, dan mudah dibaca. Contohnya pada komponen InstagramProfile, kita dapat menggunakan object destructuring dalam mengakses nilai propertinya. Sehingga, kita tidak perlu menuliskan kode satu per satu dalam membuat variabel lokal yang menampung nilai dari props.
function InstagramProfile({ name, username, bio, isVerified }) { return ( <div className="container"> <dl> <dt>Name: </dt> <dd>{name}</dd> <dt>Username: </dt> <dd>{username}</dd> <dt>Bio: </dt> <dd>{bio}</dd> <dt>Verified: </dt> <dd>{isVerified ? 'yes' : 'no'}</dd> </dl> </div> ); }
Terakhir, ketika menggunakan nilai properti, tanamkan di pikiran Anda bahwa properti bersifat read-only alias hanya boleh dibaca dan tidak boleh diubah nilainya. React component harus bersifat pure, salah satunya dengan tidak mengubah nilai yang diberikan melalui sebuah parameter atau properti. Hal ini sama seperti prinsip pure function pada functional programming. Jika di dalam component Anda menuliskan kode yang mengubah nilai dari properti, silakan evaluasi kode tersebut. Pastikan Anda tidak melakukan perubahan pada nilainya.
Catatan: UI aplikasi memang bersifat dinamis dan seringkali berubah seiring terjadinya interaksi oleh pengguna. Namun, data di dalam komponen yang bertugas untuk menampung perubahan bukanlah props, melainkan state. Jangan khawatir akan state saat ini karena kami akan membahas state pada component di modul selanjutnya.
Children
React component memiliki satu properti spesial bernama children. Properti ini spesial karena cara memberikan nilainya berbeda dengan properti biasa. Anda sudah mengetahui bahwa pemberian nilai properti pada component dilakukan sama seperti pemberian nilai atribut HTML.
Contoh, untuk memberikan properti name pada component SayHello, Anda bisa melakukannya dengan seperti ini.
function SayHello({ name }) { return <p>Hello, {name}!</p>; } <SayHello name="Dicoding" />; // <p> Hello, Dicoding!</p>
Cara pemberian nilai pada properti children berbeda. Alih-alih menggunakan gaya atribut seperti kode di atas, nilai children ditetapkan di antara tag pembuka <SayHello> dan tag penutup </SayHello> component.
function SayHello({ children }) { return <p>Hello, {children}!</p>; } <SayHello>Dicoding</SayHello>; // Hello, Dicoding!
Jadi, untuk menggunakan properti children, cara pemanggilan component pun harus menggunakan tag pembuka dan penutup.
Compositional Component
Component di React dapat menampung dan menghasilkan UI yang kompleks ataupun sederhana. Biasanya, React component yang kompleks dibangun dari beberapa component lain yang lebih kecil. Konsep ini dinamakan composition dan menjadi konsep inti seperti yang sudah Anda pelajari di modul Konsep Dasar React.
Semakin kecil kita membuat sebuah component, semakin reusable UI yang kita bangun dan React mendorong kita untuk membangun aplikasi dengan pendekatan composition daripada inheritance untuk menghasilkan UI yang lebih kompleks.
Mari kita ambil contoh UI di bawah ini.
Oke. Menurut Anda bagaimana cara terbaik untuk membangun UI tersebut? Apakah dengan membuat satu component besar bernama FilterableProductTable seperti berikut?
function FilterableProductTable() { return ( <div className="container"> <div className="search-bar__container"> <input type="text" placeholder="Search..." /> <div className="search-bar__in_stock_checkbox"> <input type="checkbox" /> <label>Only show products in stock</label> </div> </div> <div className="product-table__container"> <table> <tr> <th>Name</th> <th>Price</th> </tr> <tr> <td colSpan="2"> <strong>Sporting Goods</strong> </td> </tr> <tr> <td>Football</td> <td>$49.99</td> </tr> <tr> <td>Baseball</td> <td>$9.99</td> </tr> <tr> <td>Basketball</td> <td>$29.99</td> </tr> <tr> <td colSpan="2"> <strong>Electronics</strong> </td> </tr> <tr> <td>iPod Touch</td> <td>$99.99</td> </tr> <tr> <td>iPhone 5</td> <td>$399.99</td> </tr> <tr> <td>Nexus 7</td> <td>$199.99</td> </tr> </table> </div> </div> ); }
Tentu tidak ya! Jika Anda menghadapi kasus seperti ini, pecahlah component besar menjadi beberapa component yang lebih kecil. Mungkin Anda bertanya-tanya, bagaimana caranya kita mengetahui kapan harus membuat component secara terpisah?
Jawabannya adalah gunakan intuisi Anda untuk memutuskan apakah membutuhkan fungsi baru atau tidak. Namun, jangan lupa selalu benamkan dalam pemikiran Anda bahwa setiap fungsi haruslah memiliki satu tanggung jawab saja (single-responsibility principle). Nah, component pun sama. Idealnya, ia hanya melakukan satu hal saja. Jika memang component haruslah kompleks, ia akan memiliki beberapa component kecil lainnya.
Agar lebih mudah lagi dalam menentukannya, sketsakan pemecahan UI-nya seperti ini.
Sketsa di atas menunjukkan UI dapat dipecah menjadi 5 bagian component. Berikut nama dan tugas dari component tersebut.
- FilterableProductTable (kuning): Sebagai container atau penampung seluruh UI yang perlu ditampilkan.
- SearchBar (biru): Menerima input dari pengguna.
- ProductTable (hijau): Sebagai tabel yang menampilkan data hasil dari input pengguna.
- ProductCategoryRow (biru muda): Menampilkan heading untuk setiap kategori produk.
- ProductRow (merah): Menampilkan item produk.
Catatan: Jika Anda perhatikan pada component ProductTable, terdapat header--bertuliskan name dan price--yang tidak kami jadikan sebagai component tersendiri. Hal ini sebenarnya preferensi masing-masing apakah mau dibuatkan component terpisah atau tidak. Kami tidak memisahkan heading karena ia hanyalah teks statis dan masih bagian dari tanggung jawab ProductTable dalam menampilkan tabel. Namun, jika Anda ingin menambahkan fungsi sorting pada heading tersebut, pecahlah heading menjadi ProductTableHeader component.
Setelah mengidentifikasi pemecahan component, mari kita refactor kode dalam membuat FilterableProductTable component menjadi seperti ini.
function SearchBar() { return ( <div className="search-bar__container"> <input type="text" placeholder="Search..." /> <div className="search-bar__in_stock_checkbox"> <input type="checkbox" /> <label>Only show products in stock</label> </div> </div> ); } function ProductCategoryRow({ name }) { return ( <tr> <td colSpan="2"> <strong>{name}</strong> </td> </tr> ); } function ProductRow({ name, price }) { return ( <tr> <td>{name}</td> <td>{price}</td> </tr> ); } function ProductTable() { return ( <div className="product-table__container"> <table> <tr> <th>Name</th> <th>Price</th> </tr> <ProductCategoryRow name="Sporting Goods" /> <ProductRow name="Football" price="$49.99" /> <ProductRow name="Baseball" price="$9.99" /> <ProductRow name="Baseketball" price="$49.99" /> <ProductCategoryRow name="Electronics" /> <ProductRow name="iPod Touch" price="$99.99" /> <ProductRow name="iPhone 5" price="$399.99" /> <ProductRow name="Nexus 7" price="$199.99" /> </table> </div> ); } function FilterableProductTable() { return ( <div className="container"> <SearchBar /> <ProductTable /> </div> ); }
Berikut adalah hirarki dari component di atas.
-
FilterableProductTable
- SearchBar
-
ProductTable
- ProductCategoryRow
- ProductRow
Latihan Membuat dan Komposisi React Component
Setelah memahami materi yang diberikan tentang React component, kini saatnya kita latihan untuk membuat UI yang reusable memanfaatkan React Component. Berikut tujuan dari latihan kali ini.
- Membuat React component menggunakan fungsi JavaScript.
- Membuat React component menjadi reusable dengan memanfaatkan props.
- Komposisi React component guna membangun component yang kompleks.
Agar latihannya terasa segar, kita akan membuat UI yang berbeda dari latihan sebelumnya. Saat ini kami mengambil tema “berita”, alias website yang menampilkan daftar berita sederhana.
- Silakan buka kembali dicoding-react-starter karena kita akan menuliskan kode di sana.
-
Sebelum mulai menuliskan kode, ada baiknya kita telaah dulu UI yang akan dibuat. Buatlah sketsa agar mudah dalam memecah component yang akan dibuat.
Ada 6 component yang akan kita buat dalam menyusun UI tersebut. Berikut penjelasan masing-masing component-nya:
- News (oranye) : Component yang bertanggung jawab sebagai parent untuk menampung seluruh UI yang ditampilkan.
- Header (biru tua) : Component yang bertanggung jawab sebagai UI header dari News.
- Card (hijau) : Component yang bertanggung jawab sebagai parent untuk menampung card (item) dari berita. Component ini nantinya akan digunakan kembali untuk menampilkan item berita dengan data yang berbeda.
- CardHeader (biru muda) : Component yang bertanggung jawab menampilkan bagian header dari item berita.
- CardBody (merah) : Component yang bertanggung jawab menampilkan bagian body dari item berita.
- Button (ungu) : Component yang bertanggung jawab untuk menampilkan tautan ke berita (dumi).
-
Lanjut! Sketsa di atas menunjukkan bahwa kita perlu membuat 6 component. Agar proses pembuatan masing-masing component-nya terasa mudah, buatlah placeholder dari setiap component-nya terlebih dahulu dengan kode berikut.
import React from 'react'; import { createRoot } from 'react-dom/client'; function Button() { // TODO: selesaikan component-nya } function CardHeader() { // TODO: selesaikan component-nya } function CardBody() { // TODO: selesaikan component-nya } function Card() { // TODO: selesaikan component-nya } function Header() { // TODO: selesaikan component-nya } function News() { // data news const someNews = [ { title: 'CNN Acuire BEME', date: 'March 20 2022', content: "CNN purchased Casey Neistat's Beme app for $25million.", image: 'https://source.unsplash.com/user/erondu/600x400', category: 'News', link: '#' }, { title: 'React and the WP-API', date: 'March 19 2022', content: 'The first ever decoupled starter theme for React & the WP-API.', image: 'https://source.unsplash.com/user/ilyapavlov/600x400', category: 'News', link: '#' }, { title: 'Nomad Lifestyle', date: 'March 19 2022', content: 'Learn our tips and tricks on living a nomadic lifestyle.', image: 'https://source.unsplash.com/user/erondu/600x400', category: 'Travel', link: '#' } ]; // TODO: selesaikan component-nya return <div>Selesaikan componentnya</div>; } const root = createRoot(document.getElementById('root')); root.render(<News />);
Masih ingatkah Anda dengan materi Unidirectional Data Flow di modul Konsep Dasar React? Di sana kami menyebutkan bahwa data hanya disimpan pada induk component. Jika child component butuh mengakses datanya, data akan dikirim dari parent component melalui properti.
Oleh karena itu, kami menyimpan data someNews di dalam component News. Alasannya karena component tersebut bertugas sebagai parent untuk menampung seluruh UI yang akan ditampilkan pada Browser.
Simpan perubahan kode di atas dan tampilan browser CodeSandBox akan tampak seperti berikut.
Setelah menyiapkan placeholder, selanjutnya kita akan selesaikan component-nya satu per satu.
-
Agar mudah, kita akan mulai membuat component yang paling sederhana dulu. Indikasinya adalah component tersebut tidak nested alias tidak membutuhkan component lain di dalamnya. Contohnya adalah component Button.
Yuk kita selesaikan componentnya dengan menulis kode seperti ini pada fungsi Button.
function Button({ link }) { return <a href={link}>Find out more</a>; }
Component Button menerima satu properti yaitu link yang merupakan alamat dari berita yang ditampilkan. Nilai dari properti link nantinya akan diberikan oleh induk component-nya yaitu CardBody (ingat konsep unidirectional data flow!).
Oke, component Button sudah selesai dibuat. Mudah ‘kan? Kita bisa lanjut ke component lain.
-
Sekarang kita selesaikan component CardHeader. Silakan tuliskan kode berikut.
function CardHeader({ image, category }) { return ( <header> <h4>{category}</h4> <img src={image} alt="" /> </header> ); }
Jika dilihat pada sketsa, CardHeader bertugas untuk menampilkan bagian header dari item berita (Card). Di sana terdapat informasi kategori dan gambar dari berita. Itulah mengapa CardHeader yang kita buat menerima dua properti yaitu image dan category. Paham ‘kan?
Jika sudah paham, yuk beralih ke component lainnya.
-
Selanjutnya kita selesaikan component CardBody dengan menulis kode berikut.
function CardBody({ date, title, content, link }) { return ( <div> <p>{date}</p> <h2>{title}</h2> <p>{content}</p> <Button link={link} /> </div> ); }
Berkaca pada sketsa yang ada, CardBody bertugas untuk menampilkan informasi tanggal, judul, dan konten berita. Itulah mengapa component ini memiliki properti date, title, dan content.
Hal menarik dari component ini adalah kita komposisikan dengan penggunaan component Button (yang sebelumnya sudah dibuat). Karena penggunaan component Button membutuhkan nilai link, tentu CardBody perlu menyediakannya (yang akan diberikan oleh induk CardBody melalui properti).
-
Component selanjutnya yang akan kita selesaikan adalah Card. Silakan tulis kode berikut.
function Card({ image, category, date, title, content, link }) { return ( <article> <CardHeader image={image} category={category} /> <CardBody date={date} title={title} content={content} link={link} /> </article> ); }
Di component ini, kita komposisikan penggunaan component CardHeader dan CardBody yang sebelumnya sudah dibuat. Karena component Card menggunakan kedua komponen tersebut, ia harus menyediakan seluruh data yang dibutuhkan melalui properti.
-
Lanjut ke component Header. Silakan tuliskan kode berikut.
function Header({ title, subtitle }) { return ( <header> <h1>{title}</h1> <p>{subtitle}</p> </header> ); }
Di sketsa, component header ini menampilkan 2 informasi, yakni judul dan subjudul. Jadi, kita sediakan 2 properti bernama title dan subtitle.
Sebetulnya, eksistensi component Header ini bersifat preferensi. Tak salah bila Anda menganggap komponen ini tidak perlu dibuat terpisah dan bisa langsung menuliskan element pada component News. Namun, bila Anda ingin Header ini bersifat reusable, tidak ada salahnya untuk menjadikannya component terpisah.
-
Terakhir, kita selesaikan pembuatan component News. Di component ini, sebenarnya kita hanya tinggal menggunakan komponen yang sudah dibuat sebelumnya dan memberikan data melalui properti agar dapat tampil pada Browser.
Silakan tuliskan kode berikut.
function News() { // data news const someNews = [ { title: 'CNN Acuire BEME', date: 'March 20 2022', content: "CNN purchased Casey Neistat's Beme app for $25million.", image: 'https://source.unsplash.com/user/erondu/600x400', category: 'News', link: '#' }, { title: 'React and the WP-API', date: 'March 19 2022', content: 'The first ever decoupled starter theme for React & the WP-API.', image: 'https://source.unsplash.com/user/ilyapavlov/600x400', category: 'News', link: '#' }, { title: 'Nomad Lifestyle', date: 'March 19 2022', content: 'Learn our tips and tricks on living a nomadic lifestyle.', image: 'https://source.unsplash.com/user/erondu/600x400', category: 'Travel', link: '#' } ]; // TODO: selesaikan component-nya return ( <div> <Header title="Latest News" subtitle="Covering March & April 2022" /> <Card title={someNews[0].title} date={someNews[0].date} content={someNews[0].content} image={someNews[0].image} category={someNews[0].category} link={someNews[0].link} /> <Card title={someNews[1].title} date={someNews[1].date} content={someNews[1].content} image={someNews[1].image} category={someNews[1].category} link={someNews[1].link} /> <Card title={someNews[2].title} date={someNews[2].date} content={someNews[2].content} image={someNews[2].image} category={someNews[2].category} link={someNews[2].link} /> </div> ); }
Simpan kode tersebut dan kini Browser akan menampilkan data someNews.
Berhasil ‘kan? Lihat betapa reusable-nya component Card yang kita buat. Cukup dengan membuat satu component, kita dapat menampilkan daftar berita dengan data yang berbeda-beda. Component merupakan salah satu fitur yang membuat React sangat powerful.
Kode dalam menetapkan properti pada component Card sebetulnya bisa kita tuliskan dengan cara yang lebih baik lagi. Karena nama dari properti objek news (item dari someNews) identik dengan nama properti yang dibutuhkan oleh component Card, pemberian nilai propertinya dapat dipersingkat menggunakan spread operator seperti ini.
<Card {...someNews[0]} /> <Card {...someNews[1]} /> <Card {...someNews[2]} />
Sehingga, Anda tidak perlu repot menuliskan dan memetakkan nilai properti secara manual. Namun, teknik ini hanya dapat dilakukan bila nama properti dari objek yang di-spread sama dengan nama properti pada component.
Latihan Membuat List UI
Di latihan sebelumnya, Anda sudah berhasil menampilkan UI dengan memanfaatkan component. Anda juga sudah berhasil mempraktikkan teknik composition dalam membuat component yang kompleks. Dengan component dan teknik composition, membuat UI yang dibangun React menjadi sangat reusable dan powerful.
Di latihan kali ini, Anda akan belajar bagaimana cara menampilkan UI dalam bentuk list (daftar) menggunakan React. Tujuan utama kita adalah mengubah penggunaan component Card yang dilakukan secara manual dan repetitif agar penulisannya lebih efektif.
<Card {...someNews[0]} /> <Card {...someNews[1]} /> <Card {...someNews[2]} />
Namun, sebelum itu, ada penjelasan singkat yang ingin kami bahas mengenai pembuatan list di React.
Penjelasan Singkat Mengenai List di React
Dalam memabangun aplikasi, list merupakan hal yang fundamental. Kami yakin hampir setiap aplikasi yang pernah Anda buat, terdapat data yang perlu ditampilkan dalam bentuk list.
Beberapa Framework JavaScript (selain React) memiliki API (cara) khusus dalam menampilkan list, contohnya Vue dan Angular.
// Vue <ul id="news"> <li v-for="news in someNews">{{ news.title }}</li> </ul>
// Angular <ul id="news"> <li *ngFor="let news of someNews">{{ news.title }}</li> </ul>
Lain halnya dengan React yang mengambil pendekatan yang berbeda. Sebisa mungkin, React tetap mencoba tingkatan API yang dimilikinya seminimal mungkin. Kebanyakan React mengandalkan fitur yang sebenarnya sudah dimiliki JavaScript secara standar. Termasuk teknik dalam menampilkan list.
Jika melihat kembali contoh kode Vue dan Angular, tujuan utamanya adalah me-render list item (li) sebanyak item yang berada di array someNews. Apakah Anda tahu bahwa tujuan tersebut sebenarnya mampu dilakukan hanya menggunakan JavaScript standar? Alih-alih membuat API baru untuk menampilkan list di React, kita bisa manfaatkan fungsi array map seperti ini.
<ul id="news"> { someNews.map((news) => <li>{news.title}</li>) } </ul>
Sangat jelas ‘kan? Tidak ada API baru yang perlu Anda ingat dan pelajari. Jika Anda mengetahui cara penggunaan map, Anda akan langsung mengerti bagaimana cara membuat list di React.
Jika sudah paham kita mulai latihannya.
-
Pastikan Anda masih membuka proyek latihan sebelumnya. Jika sudah tertutup, silakan ulang kembali to-do yang ada di materi sebelumnya.
-
Fokus pada kode yang berada di dalam component News, silakan ubah penggunaan component Card yang repetitif menjadi seperti ini.
function News() { // data news const someNews = [ { title: 'CNN Acuire BEME', date: 'March 20 2022', content: "CNN purchased Casey Neistat's Beme app for $25million.", image: 'https://source.unsplash.com/user/erondu/600x400', category: 'News', link: '#' }, { title: 'React and the WP-API', date: 'March 19 2022', content: 'The first ever decoupled starter theme for React & the WP-API.', image: 'https://source.unsplash.com/user/ilyapavlov/600x400', category: 'News', link: '#' }, { title: 'Nomad Lifestyle', date: 'March 19 2022', content: 'Learn our tips and tricks on living a nomadic lifestyle.', image: 'https://source.unsplash.com/user/erondu/600x400', category: 'Travel', link: '#' } ]; return ( <div> <Header title="Latest News" subtitle="Covering March & April 2022" /> {someNews.map((news) => ( <Card {...news} /> ))} </div> ); }
Simpan perubahannya dan pastikan UI yang sama masih tampak pada Browser.
Kini kita tidak perlu lagi menggunakan component Card secara manual sebanyak item dari array. Dengan menggunakan map, kita dapat melakukannya secara otomatis. Keren ‘kan?
-
Sayangnya, dalam menampilkan list di React tak hanya sampai di sini. Coba Anda lihat console browser pada CodeSandbox, pasti ada pesan eror yang muncul seperti ini.
Ada sedikit hal yang perlu kita tambahkan ketika me-render React element atau component sebagai list, yaitu properti key pada tiap item element/component yang hendak ditampilkan. Tujuannya adalah sebagai tanda bahwa masing-masing element/component yang ditampilkan adalah unik.
Agar nilai key ini unik, kita beri saja judul dari berita (news.title). Silakan tambahkan kode berikut pada penggunaan component Card.
<Card {...news} key={news.title} />
Pastikan eror tersebut sudah tidak muncul lagi (lakukan clear console terlebih dulu dan reload browser-nya).
Mengapa React membutuhkan properti key dalam me-render list? Alasannya adalah performa. Dengan memberikan nilai unik melalui properti key, React dapat mengetahui item mana yang berubah ketika terjadi perubahan data dan me-render ulang component yang datanya berubah saja. Hal ini sangat memengaruhi performa bila menampilkan banyak daftar item.
Sebelumnya : Konsep Dasar React | Selanjutnya : Membuat Aplikasi Daftar Kontak |
0 Komentar