Pengantar React, bagian 2
Diterbitkan: 2020-07-16Selamat datang kembali di pengantar React kami, di mana kami mengajarkan Anda dasar-dasarnya sehingga Anda memahami cara kerja teknologi ini dan dengan demikian menulis kode yang lebih baik dan membuat antarmuka pengguna yang lebih baik. Pada postingan sebelumnya, kita telah membahas tentang bagaimana Anda dapat membuat komponen React sebagai fungsi murni sederhana. Mantra yang saya ulangi berulang-ulang adalah bahwa «komponen React adalah fungsi sederhana yang mendapatkan sekumpulan properti ( props ) dan menghasilkan beberapa HTML».
Terakhir kali kita berbicara tentang React, kita mengakhirinya dengan pertanyaan berikut: jika sebuah komponen adalah fungsi yang sangat sederhana, bagaimana kita bisa melakukan sesuatu yang berguna dengannya? Nah, hari ini kita akan berbicara tentang bagian dinamis dari React: yaitu, bagaimana kita dapat membuat komponen bereaksi terhadap peristiwa pengguna .
Menyiapkan Lingkungan
Bagian pertama dari tutorial ini memiliki beberapa teori tetapi tidak menyertakan contoh apa pun, dan saya mohon maaf untuk ini; Saya pikir cara terbaik untuk belajar adalah dengan melakukan, jadi mari kita perbaiki ini! Mulai sekarang, semua yang akan saya ajarkan akan didasarkan pada contoh yang akan kita kerjakan, jadi mari kita siapkan lingkungan yang akan kita gunakan terlebih dahulu.
Saya akan menganggap Anda memiliki situs WordPress yang dapat Anda kerjakan, serta node alat dev dan npm . Jika bukan itu masalahnya, dalam posting ini saya menjelaskan bagaimana Anda dapat menggunakan Lando untuk membuat instalasi WordPress lokal, dan npm memiliki semua yang perlu Anda ketahui untuk menginstal node dan npm .
Pertama, mari kita buat plugin WordPress sederhana di mana kita akan memiliki komponen React kita. Untuk melakukan ini, buat folder bernama react-example di wp-content/plugins dan letakkan file react-example.php di dalamnya dengan konten berikut:
<?php /** * Plugin Name: React Example * Description: Example. * Version: 1.0.0 */ namespace React_Example; defined( 'ABSPATH' ) or die(); function add_page() { add_menu_page( 'React Example', 'React Example', 'read', 'react-example', function () { echo '<div></div>'; } ); } add_action( 'admin_menu', __NAMESPACE__ . '\add_page' ); function enqueue_scripts() { $screen = get_current_screen(); if ( 'toplevel_page_react-example' !== $screen->id ) { return; } $dir = untrailingslashit( plugin_dir_path( __FILE__ ) ); $url = untrailingslashit( plugin_dir_url( __FILE__ ) ); if ( ! file_exists( "{$dir}/build/index.asset.php" ) ) { return; } $asset = include "{$dir}/build/index.asset.php"; wp_enqueue_script( 'react-example', "{$url}/build/index.js", $asset['dependencies'], $asset['version'], true ); } add_action( 'admin_enqueue_scripts', __NAMESPACE__ . '\enqueue_scripts' );Plugin hanya menambahkan halaman baru di Dashboard WordPress Anda yang disebut React Example dan memuat file JavaScript di dalamnya. Untuk saat ini, hasilnya akan menjadi halaman kosong:

yang seharusnya tidak mengejutkan, mengingat kami belum mengimplementasikan apa pun di JavaScript.
Seperti yang kita lihat di posting sebelumnya tentang cara menambahkan tombol ke Gutenberg, Anda harus menjalankan perintah berikut di terminal Anda (di folder plugin yang kami buat):
npm init npm install --save-dev @wordpress/scripts jika Anda ingin dapat menulis komponen React dan mentranspile JavaScript, cukup ikuti petunjuk di layar. Oh, dan jangan lupa untuk memperbarui file package.json Anda sehingga menyertakan semua scripts relevan yang diperlukan oleh @wordpress/scripts .
Terakhir, buat folder src dengan file index.js berikut:
// Import dependencies import { render } from '@wordpress/element'; // Create component const HelloWorld = () => <div>Hello World</div>; // Render component in DOM const wrapper = document.getElementById( 'react-example-wrapper' ); render( <HelloWorld />, wrapper ); Jalankan npm run build (atau npm run start jika Anda ingin kode ditranspilasikan secara otomatis setiap kali Anda mengubah file sumber), segarkan halaman dan, voila , Anda telah menyiapkan semuanya:

Membuat Komponen Fungsional Reaktif di React
Sekarang mari kita buat komponen yang bereaksi terhadap peristiwa pengguna. Contoh yang saya ingin kita terapkan bersama adalah yang ini:

penghitung sederhana yang memungkinkan Anda untuk menambah atau mengurangi nilainya dengan menggunakan tombol + dan - masing-masing. Saya tahu ini sangat sederhana, tetapi saya harap ini akan membantu Anda memahami perbedaan antara "model data" dan "antarmuka pengguna", serta memandu Anda melalui penerapan komponen dinamis.
Organisasi Kode yang Lebih Baik
Mari kita mulai dengan meningkatkan organisasi kode kita. Contoh hari ini sangat sederhana sehingga Anda mungkin ingin melewatkan langkah ini, tetapi saya pikir akan sangat membantu untuk mengaturnya dari awal.
Di src , buat components folder baru yang akan berisi semua komponen yang digunakan oleh aplikasi kita. Karena contoh hari ini hanya memiliki satu komponen, Counter , yang perlu kita lakukan hanyalah membuat satu file, counter.js :
export function Counter() => ( <p>Counter</p> ); yang, seperti yang Anda lihat, cukup mengekspor fungsi yang bertanggung jawab untuk merender komponen kita. Kemudian, ubah src/index.js sehingga alih-alih merender sampel HelloWorld kami, ia mengimpor dan menggunakan komponen Penghitung baru kami:
// Import dependencies import { render } from '@wordpress/element'; import { Counter } from './components/counter'; // Render component in DOM const wrapper = document.getElementById( 'react-example-wrapper' ); render( <Counter />, wrapper );Dan itu saja!
Menerapkan Komponen Penghitung
Tujuan hari ini adalah untuk mengimplementasikan komponen yang melacak nilai penghitung, yang dapat kita tambah atau kurangi dengan mengklik beberapa tombol. Ini berarti komponen kita harus memiliki tiga hal:
- Elemen untuk menampilkan nilai saat ini
- Tombol A + untuk meningkatkan nilai tersebut
- A - tombol untuk menguranginya
Menerapkan komponen ini cukup mudah:
export const Counter = ( { value } ) => ( <div> <div>Counter: <strong>{ value }</strong></div> <button>+</button> <button>-</button> </div> ); karena Anda tahu bahwa komponen Anda mengambil value sebagai salah satu propertinya dan harus menyertakan dua tombol. Sayangnya, Anda mungkin tidak tahu apa yang harus dilakukan selanjutnya jika Anda ingin tombol tersebut mengubah nilainya, khususnya jika kita memperhitungkan bahwa, terakhir kali kita membicarakan hal ini, saya memberi tahu Anda "komponen tidak dapat mengubah propertinya."

Fungsi Sebagai Alat Peraga dan Pemisahan Tanggung Jawab
Ingat: komponen React adalah fungsi yang menerima properti dan menghasilkan HTML. Artinya, siapa pun yang menjalankan fungsi ini (atau, dengan kata lain, siapa pun yang menggunakan komponen ini) harus memberikan semua parameter (properti) yang dibutuhkannya.
Intuisi Anda telah memberi tahu Anda bahwa nilai penghitung adalah salah satu properti yang dibutuhkannya . Kami tidak tahu dari mana nilai ini berasal (dan kami tidak peduli), tetapi kami tahu komponen kami akan diberi nilai ini. Anda juga tahu bahwa komponen Penghitung kami harus dapat mengubah nilai ini entah bagaimana . Dengan kata lain, komponen harus sedemikian rupa sehingga, ketika pengguna mengklik + atau - , nilainya harus diperbarui.
Jika Anda berpikir sejenak tentang pernyataan ini, Anda akan segera menyadari bahwa komponen Penghitung tidak hanya mengharapkan value (bertipe number ), tetapi juga membutuhkan dua properti tambahan dari fungsi tipe: satu yang meningkatkan nilai tersebut, dan yang lainnya salah satu yang mengurangi itu. Dengan kata lain, Counter membutuhkan tiga props yang berbeda :
-
value: itu angka dan nilai penghitung (duh!) -
onIncrease: itu adalah fungsi yang, ketika dipanggil, meningkatkan nilai penghitung -
onDecrease: itu adalah fungsi lain yang, ketika dipanggil, menurunkan nilai penghitung
Jika kita bekerja dengan asumsi bahwa komponen kita akan diberikan tiga props ini, komponen itu sendiri menjadi sangat sederhana:
export const Counter = ( { value, onIncrease, onDecrease } ) => ( <div> <div>Counter: <strong>{ value }</strong></div> <button onClick={ onIncrease }>+</button> <button onClick={ onDecrease }>-</button> </div> ); Perhatikan bagaimana komponen kita tidak menjalankan fungsi yang diterimanya (yang, seperti yang telah kita katakan, adalah "dilarang" karena akan memicu efek samping). Yang dilakukannya hanyalah menghubungkannya ke acara click tombol kami. Ini berarti kami telah berhasil mengimplementasikan fungsi murni (sebagaimana seharusnya semua komponen) karena, dengan tiga properti yang sama, hasilnya akan selalu menjadi HTML yang sama dengan "koneksi" yang sama.
Sayangnya, jika Anda mencoba menggunakan komponen tersebut, Anda tidak akan melihat apa pun yang berhasil
Memberikan Komponen SEMUA alat peraga yang dibutuhkan
Dan tidak heran itu tidak berhasil! Saat kami menggunakan komponen ini, kami tidak menghormati kontraknya dan kami tidak menambahkan alat peraga yang diperlukan untuk bekerja dengan benar. Lihat saja index.js :
render( <Counter />, wrapper ); Penghitung tidak memiliki value dan juga tidak memiliki fungsi onIncrease atau onDecrease !
Nah, mari kita perbaiki yang ini dengan cepat. Yang harus kita lakukan adalah membuat variabel yang menyimpan nilai penghitung dan mengimplementasikan fungsi yang memperbaruinya, sehingga kita dapat menggunakannya di komponen kita:
// Import dependencies import { render } from '@wordpress/element'; import { Counter } from './components/counter'; // Store value let value = 0; function setValue( newValue ) { value = newValue; } // Render component in DOM const wrapper = document.getElementById( 'react-example-wrapper' ); render( <Counter value={ value } onIncrease={ () => setValue( value + 1 ) } onDecrease={ () => setValue( value - 1 ) } />, wrapper );Berkat arsitektur ini, kami berhasil memisahkan antarmuka pengguna (yang merupakan komponen) sepenuhnya dari manajemen data. Komponen sepenuhnya agnostik tentang siapa atau bagaimana nilai disimpan; yang ia pedulikan adalah ia mendapatkan alat peraga yang dibutuhkannya.
Jika, sekali lagi, kami me-refresh halaman, Anda akan melihat bahwa sekarang penghitung memang menampilkan nilai penghitung default (yaitu 0 ), tetapi mengklik + dan - belum berfungsi…
Re-render Komponen pada Pembaruan
Jika Anda melihat cuplikan sebelumnya, Anda mungkin berpikir bahwa semuanya seharusnya berfungsi sekarang. Tapi jelas mereka tidak… jadi apa yang salah? Nah, mari kita jalankan tes kecil. Ubah fungsi setValue sehingga, selain menetapkan nilai baru ke value , itu juga mencatatnya di konsol:
function setValue( newValue ) { value = newValue; console.log( 'Value is', value ); }dan periksa lagi apakah semuanya berfungsi seperti yang diharapkan. Cukup buka alat pengembang browser Anda dan klik tombol Anda:

Menarik, bukan? Sepertinya value diperbarui dengan benar setiap kali pengguna mengklik tombol, tetapi komponen tidak pernah diperbarui.
Jika Anda ingin merender suatu komponen, Anda perlu menjalankan fungsi murninya dengan props yang diperlukan. Saat prop berubah, Anda perlu memanggil fungsi murni lagi dengan nilai baru, sehingga HTML baru dapat dibuat. Jadi, jika kita ingin UI kita menampilkan value terbaru , kita perlu merender ulang komponen secara manual setiap kali value diperbarui:
// Import dependencies import { render } from '@wordpress/element'; import { Counter } from './components/counter'; // Store value let value = 0; function setValue( newValue ) { value = newValue; refreshComponent(); } // Render component in DOM const wrapper = document.getElementById( 'react-example-wrapper' ); function refreshComponent() { render( <Counter value={ value } onIncrease={ () => setValue( value + 1 ) } onDecrease={ () => setValue( value - 1 ) } />, wrapper ); } refreshComponent(); Seperti yang Anda lihat, kami baru saja membuat fungsi baru bernama refreshComponent yang kami gunakan untuk merender komponen pertama kali dan setiap kali value diperbarui melalui setValue . Ini menghasilkan perilaku yang diharapkan:

Betulkah? Rendering Komponen Tampak Seperti Omong kosong!
Jika Anda telah sampai sejauh ini dengan mengikuti tutorial hari ini, Anda mungkin sedikit kecewa dengan cara kami merender ulang komponen React. Dan saya tidak menyalahkan Anda—bagian terakhir dari tutorial ini memang cukup jelek. Tapi itu karena itu hanya contoh sederhana untuk menunjukkan kepada Anda bagaimana Anda dapat memisahkan "data" dari "UI."
Hari ini Anda telah mempelajari dua pelajaran yang sangat penting :
- Alat peraga yang mungkin dibutuhkan komponen tidak hanya "data" (seperti angka, string, larik, objek...) tetapi juga dapat berupa "fungsi". Ini berarti kita dapat menghubungkan fungsi-fungsi ini ke peristiwa DOM sehingga berjalan "secara otomatis" ketika pengguna melakukan tindakan tertentu dan dengan demikian memperbarui status aplikasi kita.
- Komponen (UI) dan data yang kami gunakan sepenuhnya independen satu sama lain. Komponen React tidak peduli siapa atau bagaimana props yang dibutuhkannya dikelola. Ini berarti kami dapat menerapkan solusi buruk untuk mengelola dan memperbarui
valuepenghitung kami dan semuanya akan "berfungsi."
Di posting berikutnya kami akan meningkatkan solusi ini dan menggunakan toko WordPress (yang didasarkan pada Redux) untuk mengelola status aplikasi. Jangan sampai ketinggalan!
Gambar unggulan Hermes Rivera di Unsplash.
