Contents
Pengantar Konsep Dasar React
Konsep di dalam React menjadi alasan mengapa kami menganggap React begitu spesial dan jatuh hati dengannya. Di awal pemelajaran, kami ingin Anda mengenal konsep dasar yang ada di React. Hal ini esensial untuk dipelajari karena semakin Anda memahaminya, semakin mudah dan nyaman ketika menggunakan React.
Modul ini akan mengenalkan konsep yang ada di dalam React seperti:
- Composition,
- Declarative Code,
- Unidirectional Data Flow, dan
- React tak lebih dari JavaScript.
React Element dan Component
Pada materi ini, kami akan banyak menggunakan istilah element dan component. Agar Anda tidak bingung ketika membaca materinya, kami akan menjelaskan pengertian kedua istilah tersebut secara singkat.
Element dan component di React merupakan dua hal yang sering didengar ketika membangun antarmuka pengguna. Pasalnya, seluruh tampilan antarmuka yang dibangun menggunakan React merupakan element.
Sama halnya seperti element pada standar DOM. Element di React bisa berupa paragraph, button, image, dan tipe lainnya. Bedanya, React element hanya sebatas objek JavaScript biasa yang mengandung informasi tentang bagaimana antarmuka pengguna harus ditampilkan.
Berikut contoh dari objek React element paragraf.
{ type: 'p', props: { className: 'p-blue', children: 'Content of paragraph.', }, }
Bila objek di-render pada DOM (tentu dengan bantuan ReactDOM) maka akan menghasilkan HTML element seperti ini.
<p class="p-blue">Content of paragraph.</p>
React merupakan platform agnostic. Ia tidak tahu dan tidak peduli akan ditampilkan di web atau native (seperti Android atau iOS). Jika ia di-render menggunakan React Native, alih-alih menghasilkan HTML element, ia akan menghasilkan output UI Native.
React mampu menjadi platform agnostic karena memanfaatkan Virtual DOM. Virtual DOM bukanlah hal yang sama seperti DOM pada web. Namun, Virtual DOM hanyalah sebuah pola yang digunakan oleh React agar element mampu diadaptasikan pada banyak platform.
Oke. Jika React element mirip seperti HTML element, lantas apa itu React component?
React component hanyalah sebuah fungsi yang mengembalikan React element. Dengan React component, kita dapat mudah membuat antarmuka pengguna yang reusable. Untuk mempermudah pemahaman, anggaplah React component adalah fungsi yang mengembalikan objek seperti ini.
function Car({ manufacture, type, color }) { return { manufacture, type, color, unitCode: `${+new Date()}-${manufacture}-${type}-${color}`, } }
Fungsi di atas bersifat reusable. Mengapa? karena Anda bisa membuat objek Car dengan nilai yang berbeda hanya menggunakan fungsi yang sama.
Begitu juga React component. Namun, alih-alih mengembalikan data, React component mengembalikan sebuah UI dalam bentuk React element.
function Car({ manufacture, type, color }) { return ( <div className='car-info'> <dt>Manufacture:</dt> <dd>{manufacture}</dd> <dt>Type:</dt> <dd>{type}</dd> <dt>Color:</dt> <dd>{color}</dd> </div> ); }
React memiliki fitur JSX sehingga kita bisa menuliskan sintaks HTML pada kode JavaScript. Hal tersebut memang aneh, tetapi jangan dibuat pusing dulu ya! Kita akan membahas detail tentang JSX nanti pada modul React UI.
Salah satu keunggulan ketika menggunakan React adalah antarmuka pengguna menjadi reusable. React component sangat berperan untuk mencapai tujuan tersebut. Maka dari itu, Anda akan banyak membuat React component nantinya.
Composition
Anda mungkin sudah terbiasa memecah kode yang kompleks menjadi fungsi terpisah agar kode lebih mudah dibaca. Jika fungsi mengembalikan sebuah data, Anda juga mungkin terbiasa menggabungkan beberapa fungsi untuk menciptakan data yang lebih kompleks. Contohnya seperti ini.
function getProfilePicture(userId) { return `https://avatars.githubusercontent.com/u/${userId}`; } function getProfileLink(username) { return `https://github.com/${username}`; } function getGithubInfo(username, userId) { return { profilePicture: getProfilePicture(userId), profileLink: getProfileLink(username), }; } console.log(getGithubInfo('dimasmds', 25724809)); /** * output: { profilePicture: 'https://avatars.githubusercontent.com/u/25724809', profileLink: 'https://github.com/dimasmds' } */
Proses menggabungkan banyak fungsi untuk menciptakan data yang lebih kompleks dinamakan composition (komposisi). Di React, praktik komposisi seperti ini menjadi fondasi dan membuatnya menjadi sangat luar biasa.
Praktik komposisi di React biasa ditemukkan ketika pembuatan dan penggunaan sebuah component. Component di React bersifat reusable dan dapat dikomposisikan untuk menciptakan component yang lebih kompleks.
function ProfilePicture({ userId }) { return ( <img src={`https://avatars.githubusercontent.com/u/${userId}`} /> ); } function ProfileLink({ username }) { return ( <a href={`https://github.com/${username}`} /> ) } function GithubInfo({ username, userId }) { return ( <div className='github-info'> <ProfilePicture userId={userId} /> <ProfileLink username={username} /> </div> ) }
Komposisi merupakan language agnostic dan menjadi konsep umum pada dunia pemrograman. Intuisi dalam mempraktikkan komposisi secara alami akan sama dengan bahasa pemrograman apa pun. Jika Anda berpengalaman mempraktikkan komposisi pada bahasa pemrograman Python, intuisi Anda bisa digunakan juga ketika membuat React component.
Declarative Code
Salah satu konsep yang ada di React adalah menulis kode secara deklaratif. Mungkin Anda pernah mendengar istilah tersebut dan membandingkan dengan kode imperatif. Untuk memahami keduanya dengan jelas, kami akan menggunakan perumpamaan yang biasa terjadi di kehidupan nyata.
Anggaplah Anda sedang berkendara menggunakan mobil dan ingin suhu di dalam kabin tetap sejuk (sekitar 21 derajat). Untuk mengatur suhu, mobil menyediakan dua knop (hembusan angin dan pendingin) yang dapat dikombinasikan nilainya. Ketika berkendara di siang hari dan mulai terasa gerah, Anda perlu menaikkan nilai hembusan angin dan pendingin. Namun, bila berkendara di malam hari dan tidak ingin merasa kedinginan, Anda perlu menurunkan kedua nilainya. Model pengaturan suhu seperti ini mengharuskan Anda melakukan semuanya secara manual. Agar suhu tetap berada di kategori sejuk, Anda perlu tahu berapa nilai aliran udara dan pendingin secara tepat.
Oke. Anggaplah Anda membeli mobil baru dan kini model pengaturan suhunya berbeda. Mobil ini tidak memiliki dua knop, melainkan Anda cukup memberikan nilai suhu yang diinginkan. Suhu di kabin akan tetap stabil sesuai dengan nilai suhu yang ditetapkan, terlepas ia digunakan pada siang hari atau malam hari.
Dari dua mobil di atas, manakah yang menggunakan prinsip imperatif dan deklaratif dalam mengatur suhu? Jika masih belum paham, kita cari tahu dari arti katanya.
KBBI menjelaskan bahwa kata imperatif berarti “memerintah atau memberi komando”. Di JavaScript sendiri, kita sering menuliskan kode yang sifatnya imperatif. Ciri-cirinya adalah kita menjelaskan secara detail kepada JavaScript (lebih tepatnya transpiler) apa dan bagaimana ia harus melakukan sesuatu. Contoh, kode imperatif yang umum dituliskan di JavaScript adalah penggunaan for berikut.
const names = ['Asep', 'Alex', 'Bagus', 'Cika', 'Doni']; const uppercaseNames = []; for (let i = 0; i < names.length; i++) { uppercaseNames[i] = names[i].toUpperCase(); } console.log(uppercaseNames); /** * output: * * [ 'ASEP', 'ALEX', 'BAGUS', 'CIKA', 'DONI' ] */
Jika Anda sudah lama menggunakan JavaScript, penggunaan sintaksis for seperti di atas umum sekali dituliskan. Pada kode tersebut kita melakukan perulangan untuk memberikan nilai pada array uppercaseNames dengan butir nilai di dalam array names yang telah dikapitalkan.
Ini merupakan contoh dari kode imperatif karena kita menjelaskan perintah langkah demi langkah yang harus dilakukan JavaScript untuk mencapai tujuan tersebut. Perintah yang kita lakukan antara lain:
- menetapkan nilai awal untuk variabel iterator (let i = 0),
- memberitahu bahwa perulangan perlu dihentikan ketika i < names.length,
- mendapatkan butir nama dan mengubahnya menjadi kapital (names[i].toUpperCase()),
- menetapkan butir tersebut sebagai nilai ke-i pada array uppercaseNames, dan
- menambahkan 1 nilai pada variabel iterator i setiap kali perulangan agar prosesnya dapat terhenti.
Ingat contoh mobil pertama yang menggunakan dua knop untuk mengatur suhu? Hal ini sama seperti penggunaan for di atas karena kita perlu menginstruksikan langkah demi langkah untuk mencapai tujuan.
Lantas bagaimana dengan deklaratif? Jika dilihat dari arti katanya, deklaratif merupakan pernyataan yang sifatnya “ringkas dan jelas”. Dengan begitu kode deklaratif sangat kontras dengan kode imperatif. Ketika menuliskan kode secara deklaratif, kita tidak perlu menulis seluruh langkah untuk mendapatkan hasil yang sama. Alih-alih menuliskan perintah yang detail, kita cukup memberitahu apa yang ingin dicapai, sisanya percayakan pada JavaScript. Agar penjelasannya tak terdengar abstrak, mari kita ubah kode for di atas menggunakan kode deklaratif.
Oke, kita lihat dulu seperti apa sih yang kita inginkan. Pertama, kita lihat dulu nilai dari array names.
const names = ['Asep', 'Alex', 'Bagus', 'Cika', 'Doni'];
Dari nilai array names di atas, kita menghasilkan nilai array baru di mana seluruh nama sudah dikapitalkan.
[ 'ASEP', 'ALEX', 'BAGUS', 'CIKA', 'DONI' ]
Untuk mencapai tujuan tersebut dengan JavaScript, kita bisa menggunakan fungsi map pada array. Lihat, betapa singkat kode yang ditulis dengan gaya deklaratif.
const names = ['Asep', 'Alex', 'Bagus', 'Cika', 'Doni']; const uppercaseNames = names.map((name) => name.toUpperCase()); console.log(uppercaseNames); /** * output: * * [ 'ASEP', 'ALEX', 'BAGUS', 'CIKA', 'DONI' ] */
Di sana kita tidak lagi membuat variabel iterator; memberitahu kapan perulangan harus berhenti; dan tidak perlu menetapkan nilai pada setiap butir array secara manual. Menulis kode secara deklaratif sangat mengasyikkan, bukan?
React Merupakan Deklaratif
React sendiri menerapkan gaya deklaratif baik dari standar yang mereka tetapkan atau konvensi ketika menggunakannya. Sebagai gambaran awal saja, untuk membuat antarmuka berbentuk daftar (list), React mendorong kita untuk menggunakan gaya deklaratif. Anda bisa memanfaatkan map, filter, atau fungsi array sejenisnya.
function Contacts() { const names = ['Asep', 'Alex', 'Bagus', 'Cika', 'Doni']; return ( <ol className='contacts'> {names.map((name) => <li>{name}</li>)} </ol> ); }
Contoh lain, ketika menetapkan event pada elemen pun dilakukan secara deklaratif.
<button onClick={callContact}>Call Contact</button>
Mungkin contoh kode tersebut terlihat janggal, tapi nyatanya valid di React. Untuk menetapkan event listener, kita tidak lagi menuliskan addEventListener karena itu semua sudah diatasi oleh React.
Intinya, kode imperatif menuntut kita untuk menuliskan seluruh langkah demi langkah untuk mencapai tujuan. Namun, dengan kode deklaratif kita cukup memberitahukan apa yang ingin dicapai, sisanya percayakan pada JavaScript.
Unidirectional Data Flow
Sebelum React, Front-End Framework seperti Angular menggunakan pola two-way data binding untuk aliran data agar ia tetap sinkron dengan DOM (tampilan aplikasi).
Jika model mengubah data, data tersebut secara reaktif akan memperbarui data yang ada di view. Sebaliknya, jika pengguna mengubah data yang ada di view, data yang ada di model pun secara reaktif akan berubah. Pola aliran data seperti ini sebenarnya ciamik, tetapi terkadang menyulitkan ketika aplikasi sudah bertambah besar. Karena tak jarang developer bingung dari mana sebetulnya pembaruan data berasal. Dari view-kah? Atau model?
Berbeda halnya dengan React, aliran data di React bersifat unidirectional atau searah dari parent component (komponen induk) ke child component (komponen anak).
Di React, data terletak di parent component dan bila child component membutuhkannya, data tersebut akan dikirim dari parent component. Ketika terjadi perubahan data, parent component-lah yang dapat memperbarui datanya karena memang datanya berada di sana. Child hanya bisa mengirimkan data terbaru atau memberikan sinyal bila data perlu diperbarui oleh parent component. Ingat! Karena React bersifat reaktif, bila terjadi perubahan data di parent component, child component pun akan memiliki data terbaru.
Oke, untuk memantapkan pemahaman, mari kita tebak-tebakkan.
Anggaplah, Anda memiliki komponen bernama Delivery, di dalamnya terdapat dua child component bernama LocationPicker dan element input bertipe number. Kemudian di dalam komponen LocationPicker, terdapat dua child component bernama OriginPicker dan DestinyPicker. Dengan begitu strukturnya tampak seperti ini.
<Delivery> <LocationPicker> <OriginPicker /> <DestinyPicker /> </LocationPicker> <input type="number"/> </Delivery>
Dari kode di atas, kira-kira komponen apa saja yang bertanggung jawab untuk memperbarui data? Ingat petunjuknya adalah data hanya berada di parent element.
Jawabannya adalah komponen Delivery dan LocationPicker. Mengapa? Berikut penjelasannya.
- Delivery: Karena komponen Delivery merupakan parent dan ia menampung seluruh child component yang membentuk antarmuka pengiriman maka hanya komponen delivery yang cocok untuk memiliki seluruh data pengiriman dan juga bertanggung jawab untuk memperbaruinya.
- LocationPicker: Walaupun LocationPicker menerima data dari induknya, ternyata ia juga merupakan parent component dan sangat masuk akal bila menampung data yang dibutuhkan oleh kedua child component di dalamnya.
Selain kedua komponen tersebut, komponen lain hanyalah child element yang datanya dikirim dari parent. Jadi, mereka tidak bisa memperbarui datanya.
React is Just JavaScript
Istilah “React hanyalah JavaScript” mungkin agak sedikit bertentangan setelah kami mencontohkan banyak sintaksis yang hanya berjalan di React. Namun, istilah tersebut ada benarnya juga.
Garis besarnya adalah bila Anda sudah nyaman dengan JavaScript, pasti Anda tidak butuh waktu lama untuk memilih React dalam membangun antarmuka pengguna. Ada dua alasan mengapa demikian.
Pertama, karena tingkat abstraksi yang dibuat React sebenarnya dangkal. Anda tidak perlu mengingat banyak API baru ketika menggunakan React.
Kedua, React mencoba untuk tidak membuat fungsionalitas baru yang sudah bisa dilakukan oleh JavaScript secara standar. Contoh, di materi Declarative Code Anda melihat kami mencontohkan bagaimana membangun antarmuka dalam bentuk daftar di React. Di beberapa Framework Front-End yang ada, contohnya Vue, mereka membuat standar atribut v-for untuk melakukan proses pengulangan pada array dalam menampilkan antarmuka berbentuk daftar.
<ul id="contacts"> <li v-for="contact in contacts">{{ contact }}</li> </ul>
Namun, di React sendiri, kita menggunakan fungsi map standar dari JavaScript.
<ul> {contacts.map((contact) => ( <li>{contact}</li> ))} </ul>
Di samping siapa yang “salah” atau “jelek”, mereka memang menawarkan simplifikasi yang berbeda. Tidak usah berdebat akan hal itu.
Intinya, aplikasi React dibangun dari hal yang sebenarnya Anda sudah familier. Apa itu? JavaScript! Anda tidak perlu mempelajari template engine khusus ketika menggunakan React atau cara baru dalam melakukan sesuatu.
Sebenarnya, cukup perdalam kemampuan JavaScript dan kemampuan Anda terhadap React pun akan bertambah. Terkadang, ketika mempelajari React, kita malah menjadi JavaScript Developer yang lebih baik lagi. Jarang kita sadari, konvensi yang mulanya terlihat hanya untuk React, ternyata bisa juga dilakukan oleh JavaScript standar.
Sebelumnya : Pengenalan React | Selanjutnya : React UI Component |
0 Komentar