Cara menggunakan react bootstrap template

Kita akan membangun sebuah gim kecil sepanjang tutorial ini. Anda bisa jadi tergoda untuk melewati tutorial ini karena Anda tidak benar-benar membuat gim — namun luangkanlah sedikit waktu untuk mencobanya. Teknik-teknik yang akan Anda pelajari pada tutorial ini adalah hal-hal dasar yang digunakan untuk membangun aplikasi React, dan menguasai teknik-teknik tersebut akan memberikan pemahaman terhadap React secara lebih mendalam.

Tips

Tutorial ini didesain untuk orang yang lebih suka belajar dengan mempraktikkan. Jika Anda lebih suka mempelajari konsep dari tingkat dasar sampai tingkat lanjut, lihat panduan langkah demi langkah kami. Anda akan menyadari bahwa tutorial dan panduan akan saling melengkapi.

Tutorial ini akan dibagi menjadi beberapa bagian:

  • merupakan titik awal Anda untuk mengikuti tutorial.
  • bagian ini berisi hal-hal mendasar React: komponen, props, dan state.
  • bagian ini berisi teknik-teknik yang paling umum pada pengembangan aplikasi React.
  • bagian ini akan memberikan pemahaman yang lebih mendalam pada kekuatan unik dari React.

Anda tidak perlu menyelesaikan semua bagian sekaligus untuk mendapatkan pembelajaran dari tutorial ini. Cobalah mengerjakan semampu Anda — walaupun hanya satu atau dua bagian.

Apa yang Kita Kembangkan?

Dalam tutorial ini, kami akan menunjukkan cara membuat permainan tic-tac-toe interaktif menggunakan React.

Anda dapat melihat gambaran aplikasi yang akan kita buat di sini: Hasil Akhir. Jika kode tersebut tidak masuk akal untuk Anda, atau Anda tidak akrab dengan sintaks kode tersebut, jangan khawatir! Tujuan dari tutorial ini adalah untuk membantu Anda mengerti React dan sintaksnya.

Kami merekomendasikan Anda untuk mencari tahu tentang permainan tic-tac-toe sebelum melanjutkan tutorial ini. Salah satu fitur yang akan Anda lihat adalah adanya daftar bernomor di sebelah kanan papan permainan. Daftar ini memberikan Anda semua riwayat langkah yang sudah terjadi dalam permainan, dan terus diperbarui selama permainan berlangsung.

Anda bisa menutup laman permainan tic-tac-toe setelah Anda paham dengan permainan tersebut. Kita akan memulai dari templat sederhana pada tutorial ini. Langkah selanjutnya adalah mempersiapkan Anda sehingga Anda dapat memulai mengembangkan permainan tic-tac-toe.

Prasyarat

Kami mengasumsikan bahwa Anda memiliki pemahaman akan HTML dan JavaScript, namun Anda seharusnya tetap dapat mengikuti tutorial ini jika Anda memiliki pemahaman pada bahasa pemrograman lainnya. Kami juga berasumsi bahwa Anda memiliki pemahaman akan konsep pemrograman seperti fungsi, objek, senarai, dan pada tingkat yang lebih rendah, kelas.

Jika Anda memerlukan pengingat tentang JavaScript, kami merekomendasikan Anda untuk membaca panduan ini. Perlu diperhatikan juga bahwa kita menggunakan beberapa fitur dari ES6 — versi terbaru JavaScript. Di tutorial ini, kita menggunakan statement arrow functions, kelas, return React.createElement('div', {className: 'shopping-list'}, React.createElement('h1', /* ... h1 children ... */), React.createElement('ul', /* ... ul children ... */) );4, dan return React.createElement('div', {className: 'shopping-list'}, React.createElement('h1', /* ... h1 children ... */), React.createElement('ul', /* ... ul children ... */) );5. Anda dapat menggunakan untuk melihat hasil kompilasi kode ES6.

Mempersiapkan Tutorial

Ada dua cara untuk menyelesaikan tutorial ini: Anda dapat menulis kode pada browser Anda atau mempersiapkan local development environment pada komputer Anda.

Persiapan Cara 1: Menulis Kode pada Browser

Ini adalah cara tercepat untuk memulai!

Pertama, buka kode permulaan ini pada tab baru. Tab baru tersebut seharusnya menunjukan papan permainan tic-tac-toe yang kosong dan kode React. Kita akan mengedit kode React tersebut pada tutorial ini.

Anda dapat melewati cara kedua untuk persiapan dan menuju ke bagian untuk mendapatkan ikhtisar dari React.

Persiapan Cara 2: Local Development Environment

Cara ini murni opsional dan tidak wajib pada tutorial ini!


Opsional: Instruksi untuk mengikuti secara lokal menggunakan editor teks pilihan Anda

Persiapan ini membutuhkan lebih banyak langkah tetapi membuat Anda dapat menyelesaikan tutorial ini menggunakan editor teks pilihan Anda. Berikut adalah beberapa langkah yang harus diikuti:

  1. Pastikan Anda sudah meng-install Node.js versi terbaru.
  2. Ikuti untuk membuat project baru.

npx create-react-app my-app

  1. Hapus semua file pada folder return React.createElement('div', {className: 'shopping-list'}, React.createElement('h1', /* ... h1 children ... */), React.createElement('ul', /* ... ul children ... */) );6 dari project baru Anda.

Catatan: jangan hapus seluruh folder return React.createElement('div', {className: 'shopping-list'}, React.createElement('h1', /* ... h1 children ... */), React.createElement('ul', /* ... ul children ... */) );7, cukup file-file yang ada di dalamnya saja. Kita akan menggantikan file-file tersebut dengan contoh-contoh yang akan diberikan melalui tutorial ini.

cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..

  1. Tambahkan file bernama return React.createElement('div', {className: 'shopping-list'}, React.createElement('h1', /* ... h1 children ... */), React.createElement('ul', /* ... ul children ... */) );8 ke dalam folder return React.createElement('div', {className: 'shopping-list'}, React.createElement('h1', /* ... h1 children ... */), React.createElement('ul', /* ... ul children ... */) );6 dengan kode CSS ini.
  2. Tambahkan file bernama class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }0 ke dalam folder return React.createElement('div', {className: 'shopping-list'}, React.createElement('h1', /* ... h1 children ... */), React.createElement('ul', /* ... ul children ... */) );6 dengan kode JS ini.
  3. Tambahkan tiga baris kode berikut pada bagian paling atas class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }0 di dalam folder return React.createElement('div', {className: 'shopping-list'}, React.createElement('h1', /* ... h1 children ... */), React.createElement('ul', /* ... ul children ... */) );6:

import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';

Sekarang, jika Anda menjalankan class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }4 pada folder project Anda dan mengakses class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }5 pada browser Anda, Anda akan melihat papan tic-tac-toe yang kosong.

Kami merekomendasikan Anda untuk mengikuti instruksi ini untuk mengkonfigurasi syntax highlighting untuk editor Anda.

Tolong, Saya Mengalami Masalah!

Jika Anda mengalami masalah, silahkan kunjungi sumber dukungan komunitas. Secara khusus, Reactiflux Chat adalah langkah yang baik untuk mendapat bantuan dengan cepat. Jika Anda tidak mendapat jawaban, atau tetap mengalami masalah, maka silahkan mengajukan issue, dan kami akan membantu Anda.

Ikhtisar

Sekarang karena Anda sudah siap, mari mempelajari ikhtisar dari React!

Apa Itu React?

React adalah library JavaScript yang deklaratif, efisien, dan fleksibel untuk membangun antarmuka pengguna. React memungkinkan Anda untuk membuat antarmuka kompleks dari kumpulan kode yang kecil dan terisolasi yang disebut “komponen”.

React memiliki beberapa jenis komponen, tetapi kita akan memulai dengan subkelas class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }6:

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Daftar Belanja untuk {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Contoh Penggunaan: <ShoppingList name="Mark" />

Kita akan membahas tag aneh yang seperti XML sesaat lagi. Kita menggunakan komponen untuk memberi tahu React yang ingin kita lihat pada layar. Ketika data kita berubah, React akan memperbarui dan me-render ulang komponen kita dengan efisien.

Di sini, ShoppingList adalah kelas komponen React atau tipe komponen React. Sebuah komponen dapat menerima parameter yang disebut dengan class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }7 (singkatan dari class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }8) dan mengembalikan sebuah hirarki dari tampilan-tampilan yang akan ditampilkan via method class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9.

Method class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9 mengembalikan sebuah deskripsi dari benda yang akan Anda lihat pada layar. React mengambil deskripsi tersebut dan menampilkan hasilnya ke layar. Secara khusus, class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9 mengembalikan elemen React, yang merupakan deskripsi ringan tentang yang harus di-class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9. Kebanyakan pengembang React menggunakan sintaks khusus yang disebut “JSX” yang memudahkan struktur dari React mudah untuk ditulis. Sintaks class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }3 akan diubah menjadi class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }4 pada saat build. Contoh di atas sama dengan sintaks berikut:

return React.createElement('div', {className: 'shopping-list'}, React.createElement('h1', /* ... h1 children ... */), React.createElement('ul', /* ... ul children ... */) );

Jika Anda penasaran, class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }5 dideskripsikan dengan lebih rinci pada bagian , tetapi kita tidak akan menggunakannya pada tutorial ini. Kita akan tetap menggunakan JSX.

JSX hadir dengan kekuatan penuh dari JavaScript. Anda dapat menulis setiap ekspresi JavaScript di antara tanda kurung kurawal di dalam JSX. Setiap elemen React adalah objek JavaScript yang dapat Anda simpan di dalam variabel atau Anda oper ke seputar program Anda.

Komponen class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }6 di atas hanya me-render komponen DOM built-in seperti class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }3 dan class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }8. Namun, Anda juga dapat membuat dan me-render komponen React Anda sendiri. Contohnya, kita dapat mengacu ke seluruh daftar belanja di atas dengan menuliskan class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }9. Setiap komponen React terenkapsulasi dan dapat beroperasi secara mandiri; hal ini memungkinkan Anda untuk membangun sebuah antarmuka pengguna yang kompleks dari komponen sederhana.

Melihat Kode Permulaan

Jika Anda akan mengikuti tutorial ini di browser Anda, buka kode ini pada tab baru: Kode Permulaan. Jika Anda mengikuti tutorial ini dengan local environment Anda, bukalah class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }0 pada folder project Anda (Anda sudah pernah menyentuh file ini selama ).

Kode Permulaan ini berdasarkan pada aplikasi yang akan kita buat. Kami sudah menyediakan style CSS sehingga Anda bisa fokus mempelajari React dan memprogram permainan tic-tac-toe.

Dengan melihat kode permulaan, Anda akan melihat bahwa kita memiliki tiga komponen React:

  • Square
  • Board
  • Game

Komponen Square akan me-render sebuah class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }1 dan komponen Board akan me-render 9 persegi. Komponen Game akan me-render sebuah papan dengan nilai sementara yang akan kita ganti nanti. Saat ini belum ada komponen interaktif.

Mengoper Data Melalui Props

Untuk memulai mendalami React, mari kita mencoba untuk mengoper data dari komponen Board ke komponen Square kita.

Kami menyarankan mengetik kode-kode berikut secara manual selama Anda mengikuti tutorial ini dan menghindari menggunakan copy/paste. Ini akan membantu mengembangkan memori otot Anda dan meningkatkan pemahaman Anda mengenai React.

Di dalam method class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }2 Board, ubah kodenya untuk mengoperkan prop bernama class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }3 ke Square:

class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }

Ubah method class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9 Square untuk menampilkan nilai tersebut dengan mengganti class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }5 dengan class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }6:

class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }

Sebelum:

Sesudah: Anda seharusnya melihat angka dari setiap persegi pada keluaran yang telah di-render.

Lihat kode lengkap sampai tahap ini

Selamat! Anda baru saja “mengoperkan sebuah prop” dari komponen Board ke komponen Square. Mengoperkan props adalah cara informasi dapat mengalir dalam aplikasi React dari (komponen) induk ke anak.

Membuat Komponen Interaktif

Mari mengisi komponen Square dengan sebuah “X” ketika kita mengklik komponen tersebut. Pertama, ubah button tag yang dikembalikan dari fungsi class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }7 komponen Square menjadi:

class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }

Jika kita mengklik salah satu Square, kita akan mendapatkan alert pada browser kita.

Catatan

Untuk mempercepat proses mengetik dan menghindari perilaku membingungkan class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }8, kita akan menggunakan sintaks arrow function untuk setiap event handler yang akan kita buat:

class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }

Perhatikan bahwa dengan class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }9, kita mengoperkan sebuah fungsi sebagai prop class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }0. Fungsi tersebut hanya dieksekusi setelah klik. Lupa untuk menulis class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }1 dan menulis class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }2 adalah kesalahan yang sering terjadi, dan menyebabkan fungsi akan terus dijalankan setiap komponen di-render ulang.

Selanjutnya, kita ingin agar komponen Square “mengingat” bahwa komponen tersebut sudah diklik dan mengisinya dengan “X”. Untuk “mengingat” sesuatu, komponen menggunakan state.

Komponen React dapat memiliki state dengan mengatur class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }3 pada konstruktornya. class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }3 harus dianggap private oleh komponen React tempat ia didefinisikan. Mari menyimpan nilai Square saat ini pada class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }3 dan mengubahnya ketika Square diklik.

Pertama, kita akan menambahkan konstruktor pada kelas untuk menginisialisasi state:

class Square extends React.Component { constructor(props) { super(props); this.state = { value: null, }; } render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }

Catatan

Pada kelas JavaScript, Anda harus selalu memanggil class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }6 ketika mendefinisikan konstruktor dari sebuah subkelas. Semua kelas komponen React yang memiliki class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }7 harus dimulai dengan class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }8.

Sekarang kita akan mengubah method class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9 Square untuk menampilkan nilai state saat ini ketika diklik:

  • Mengganti class Square extends React.Component { constructor(props) { super(props); this.state = { value: null, }; } render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }0 dengan class Square extends React.Component { constructor(props) { super(props); this.state = { value: null, }; } render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }1 di dalam class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }1 tag.
  • Mengganti event handler class Square extends React.Component { constructor(props) { super(props); this.state = { value: null, }; } render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }3 dengan class Square extends React.Component { constructor(props) { super(props); this.state = { value: null, }; } render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }4.
  • Pisahkan props class Square extends React.Component { constructor(props) { super(props); this.state = { value: null, }; } render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }5 dan class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }0 pada baris yang berbeda agar lebih mudah dibaca.

Setelah perubahan di atas, tag class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }1 yang dikembalikan dari method class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9 Square akan terlihat seperti ini:

cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..0

Dengan memanggil class Square extends React.Component { constructor(props) { super(props); this.state = { value: null, }; } render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }9 dari handler class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }0 pada method class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9 Square, kita memberi tahu React untuk me-render ulang Square setiap class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }1 diklik. Setelah diperbarui, class Square extends React.Component { constructor(props) { super(props); this.state = { value: null, }; } render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }1 dari Square akan menjadi cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..04, jadi kita akan melihat cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..05 pada papan permainan. Jika Anda mengklik salah satu Square, maka akan muncul cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..05.

Ketika Anda memanggil cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..07 di sebuah component, React akan memperbarui komponen anak di dalamnya secara otomatis.

Lihat kode lengkap sampai tahap ini

Developer Tools

Ekstensi React Devtools untuk Chrome dan Firefox memungkinkan Anda untuk melihat pohon komponen dari React dengan menggunakan perangkat pengembang browser Anda.

React Devtools memungkinkan Anda untuk mengecek props dan state dari komponen React Anda.

Setelah meng-install React Devtools, Anda dapat mengklik kanan elemen manapun pada halaman Anda, kemudian klik “Inspect” untuk membuka perangkat pengembang dan tab React (“⚛️ Components” and “⚛️ Profiler”) akan muncul sebagai tab terakhir di sebalah kanan. Gunakan “⚛️ Components” untuk menginspeksi pohon komponen.

Walaupun demikian, perlu diperhatikan bahwa ada beberapa langkah tambahan untuk membuat aplikasi Anda bekerja dengan CodePen:

  1. Masuk atau daftar dan konfirmasi email Anda (diperlukan untuk mencegah spam)
  2. Klik tombol “Fork”.
  3. Klik “Change View” dan pilih “Debug mode”.
  4. Pada tab baru yang terbuka, devtools saat ini seharusnya memiliki tab React.

Menyelesaikan Permainan

Sekarang kita sudah memiliki blok-blok dasar untuk membangun permainan tic-tac-toe. Untuk menyelesaikan permainan ini, kita memerlukan penempatan alternatif “X” dan “O” pada papan dan kita memerlukan cara untuk menentukan pemenangnya.

Menaikkan State

Saat ini, setiap komponen Square mengurus state dari permainan. Untuk menentukan pemenang, kita akan mengurus nilai dari setiap persegi di satu lokasi.

Kita dapat memikirkan Board seharusnya cukup mengambil state setiap Square. Walaupun pendekatan ini mungkin di React, tetapi kami tidak menyarankannya karena kodenya akan sulit untuk dimengerti, rentan terhadap bugs, dan sulit untuk di-refactor. Sebagai gantinya, pendekatan terbaik untuk adalah untuk menyimpan state dari permainan pada komponen Board. Komponen Board dapat memberitahu setiap Square untuk menampilkan data dengan memberikannya melalui prop .

Untuk mengambil data dari beberapa anak atau membuat dua komponen anak berkomunikasi satu sama lain, Anda perlu mendeklarasikan state pada komponen induk. Komponen induk dapat memberikan state ke anak dengan menggunakan props; pola ini dapat membuat komponen-komponen anak tetap sinkron satu sama lain dan dengan komponen induk.

Menaikkan state ke komponen induk lazim ketika me-refactor komponen React. Mari memanfaatkan kesempatan ini untuk mencobanya.

Kita akan menambahkan konstruktor ke Board dan menginisialisasi state dari Board berisi array dengan 9 null. Sembilan nilai ini melambangkan 9 persegi:

cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..1

Ketika kita mengisi papan permainan nanti, senarai cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..08 akan terlihat seperti ini:

cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..2

Method class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }2 dari Board saat ini terlihat seperti ini:

cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..3

Awalnya, kita dari Board untuk menampilkan angka 0 sampai 8 di setiap Square. Pada langkah berbeda sebelumnya, kita menggantikan angka dengan “X” yang . Ini sebabnya Square saat ini mengabaikan prop class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }3 yang diberikan oleh Board.

Sekarang kita akan menggunakan mekanisme pengoperan prop lagi. Kita akan memodifikasi Board untuk memberi instruksi pada setiap Square untuk mengubah nilai saat ini (cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..04, cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..12, atau cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..13). Kita sudah mendefinisikan senarai cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..14 pada konstruktor Board dan kita akan memodifikasi method class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }2 Board untuk membaca dari state:

cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..4

Lihat kode lengkap sampai tahap ini

Setiap Square akan menerima prop class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }3 yang dapat berupa cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..04, cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..12, atau cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..13 untuk persegi kosong.

Selanjutnya, kita perlu mengubah perilaku Square saat diklik. Komponen Board saat ini mengatur persegi yang sedang diisi. Kita perlu memikirkan sebuah cara agar Square dapat memperbarui state di Board. Karena state dianggap sebagai private di dalam suatu komponen, kita tidak dapat mengubah state Board melalui Square secara langsung.

Untuk mempertahankan state privacy dari Board, kita akan memberikan sebuah fungsi dari Board ke Square. Fungsi ini akan dipanggil ketika komponen Square diklik. Kita akan mengubah method class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }2 di dalam Board menjadi:

cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..5

Catatan

Kita membagi elemen yang dikembalikan menjadi beberapa baris agar lebih mudah dibaca. Kami juga menambahkan tanda kurung sehingga JavaScript tidak menyisipkan titik koma setelah cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..21 dan merusak kode kita.

Sekarang kita memberikan dua prop dari Board ke Square: class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }3 dan class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }0. Prop class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }0 adalah sebuah fungsi yang dapat dipanggil oleh Square ketika diklik. Kita akan membuat perubahan berikut pada Square:

  • Mengganti class Square extends React.Component { constructor(props) { super(props); this.state = { value: null, }; } render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }1 dengan class Square extends React.Component { constructor(props) { super(props); this.state = { value: null, }; } render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }0 pada method class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9 Square.
  • Mengganti cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..28 dengan cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..29 pada method class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9 Square.
  • Menghapus class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }7 Square karena Square sudah tidak menyimpan state dari permainan.

Setelah perubahan tersebut, komponen Square akan terlihat seperti ini:

cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..6

Ketika sebuah Square diklik, fungsi class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }0 yang disediakan oleh Board akan dipanggil. Berikut adalah ulasan bagaimana kita dapat memperoleh hasil saat ini:

  1. Prop class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }0 pada komponen built-in DOM class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }1 memberi tahu React untuk menyiapkan event listener klik.
  2. Ketika tombol diklik, React akan memanggil event handler class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }0 yang sudah didefinisikan pada method class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }7 Square.
  3. Event handler ini memanggil cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..29. Prop class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }0 dari Square ditentukan oleh Board.
  4. Karena Board mengoperkan cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..39 ke Square, Square memanggil cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..40 ketika diklik.
  5. Kita belum mendefinisikan method cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..41, sehingga kode kita akan crash. Ketika Anda mengeklik sebuah persegi, Anda akan melihat teks error berwarna merah yang bertuliskan semacam “this.handleClick is not a function”.

Catatan

Atribut class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }0 pada elemen DOM class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }1 memiliki arti khusus untuk React karena merupakan komponen built-in. Untuk komponen komponen custom seperti Square, penamaan bersifat bebas. Kita dapat menamakan prop class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }0 Square atau cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..45 Board dengan nama lain. Namun demikian, dalam React, hal ini adalah sebuah konvensi untuk menggunakan penamaan cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..46 pada props yang merepresentasikan event dan cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..47 untuk method yang menangani event tersebut.

Ketika kita mencoba untuk mengklik salah satu Square, kita seharusnya akan mendapatkan sebuah pesan error karena kita belum mendefinisikan cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..45. Sekarang kita akan menambahkan cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..45 pada kelas Board:

cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..7

Lihat kode lengkap sampai tahap ini

Setelah perubahan ini, kita dapat mengklik Square kembali untuk mengisinya. Tetapi, sekarang state disimpan pada komponen Board, bukan pada setiap komponen Square. Ketika state Board berubah, komponen Square akan di-render ulang secara otomatis. Dengan menyimpan state dari setiap persegi pada komponen Board, kita dapat menentukan pemenangnya pada tahap berikutnya.

Karena komponen Square tidak lagi mengatur state, komponen Square menerima nilai dari komponen Board dan memberikan informasi ke komponen Board ketika diklik. Dalam istilah React, komponen Square sekarang disebut dengan controlled components. Komponen Board memiliki kontrol penuh pada komponen Square.

Perhatikan bahwa di dalam cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..45, kita memanggil cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..51 untuk membuat kopi senarai cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..14 untuk memodifikasinya sebagai ganti dari memodifikasi senarai yang ada. Kami akan menjelaskan alasan kita membuat kopi dari senarai cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..14 di bagian selanjutnya.

Mengapa Immutablility Itu Penting

Pada contoh kode sebelumnya, kami menyarankan Anda untuk menggunakan cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..51 untuk membuat kopi dari senarai cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..14 untuk memodifikasinya sebagai ganti dari memodifikasi senarai yang ada. Kita akan membahas immutability dan mengapa immutability penting untuk dipelajari.

Secara umum, ada dua pendekatan untuk mengubah data. Pendekatan pertama adalah untuk me-mutate data dengan mengubah nilai dari data secara langsung. Pendekatan kedua adalah dengan mengganti data dengan kopi baru yang memiliki perubahan yang diinginkan.

Perubahan Data dengan Mutation

cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..8

Perubahan Data Tanpa Mutation

cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..9

Hasil akhir dari kedua pendekatan sama tetapi dengan tidak melakukan mutate (atau mengganti data di dalamnya) secara langsung, kita mendapatkan keuntungan sebagai berikut.

Fitur Kompleks Menjadi Lebih Sederhana

Immutability membuat fitur kompleks menjadi lebih mudah untuk diimplementasikan. Nanti pada tutorial ini juga, kita akan mengimplementasikan fitur “penjelajahan waktu” yang memungkinkan kita untuk mengulas riwayat permainan tic-tac-toe kita dan “lompat kembali” ke langkah sebelumnya. Fungsionalitas ini tidak spesifik ke permainan — sebuah kemampuan untuk undo dan redo beberapa aksi adalah kebutuhan yang umum dalam sebuah aplikasi. Menghindari mutasi data memungkinkan kita untuk menyimpan riwayat permainan sebelumnya utuh dan menggunakannya kembali kemudian.

Mendeteksi Perubahan

Mendeteksi perubahan pada objek mutable sulit karena mereka dimodifikasi secara langsung. Deteksi ini membutuhkan objek mutable tersebut dibandingkan dengan beberapa kopi sebelumnya dari dirinya dan seluruh melintasi seluruh pohon objek.

Mendeteksi perubahan pada objek immutable dianggap lebih mudah. Jika objek immutable yang ditunjuk berbeda dengan objek sebelumnya, maka objeknya sudah berubah.

Menentukan Waktu Untuk Melakukan Render Ulang di React

Keuntungan utama dari immutability adalah membantu Anda untuk membuat pure component di React. Data yang immutable dapat dengan mudah memastikan apakah perubahan sudah terjadi, yang juga membantu untuk menentukan apakah komponen perlu di-render ulang.

Anda dapat mempelajari cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..56 lebih lanjut dan bagaimana cara membuat pure components dengan membaca .

Function Components

Sekarang kita akan mengubah Square menjadi function component.

Dalam React, function component adalah cara lebih mudah untuk menulis komponen yang hanya berisi method class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9 dan tidak memiliki state. Sebagai ganti menulis kelas yang merupakan turunan dari class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }6, kita dapat menulis sebuah fungsi yang menerima class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }7 sebagai masukan dan mengembalikan apa yang harus di-render. Menulis function component lebih tidak jemu dibanding menulis kelas dan banyak komponen dapat ditulis dengan cara ini.

Ganti kelas Square dengan fungsi berikut:

import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';0

Kita sudah mengganti cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..60 dengan class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }7 saat muncul.

Lihat kode lengkap sampai saat ini

Catatan

Ketika mengubah Square menjadi function component, kita juga mengubah cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..62 menjadi lebih pendek cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..63 (perhatikan hilangnya tanda kurung pada kedua sisi). Pada kelas, kita menggunakan arrow function untuk mengakses nilai class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }8 yang benar, tetapi di function component kita tidak perlu mengkhawatirkan class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }8.

Mengambil Giliran

Sekarang kita perlu memperbaiki kerusakan yang cukup jelas pada permainan tic-tac-toe kita: “O” tidak dapat dituliskan ke dalam papan.

Kita akan menentukan “X” mengambil giliran pertama sebagai nilai default. Kita dapat menentukan nilai default dengan mengubah state awal pada konstruktor Board:

import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';1

Setiap pemain selesai dengan langkahnya, cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..66 (sebuah boolean) akan diubah nilainya untuk menentukan siapa yang akan membuat langkah selanjutnya dan state dari permainan akan disimpan. Kita akan mengubah fungsi cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..45 dari Board untuk mengubah nilai dari cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..66:

import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';2

Dengan perubahan ini, “X” dan “O” akan mendapatkan giliran setiap satu langkah selesai.

Mari mengubah teks “status” pada class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9 di Board, sehingga teks menampilkan pemain mana yang sedang mendapat giliran selanjutnya:

import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';3

Setelah mengubahnya, Anda akan memiliki komponen Board berikut:

import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';4

Lihat kode lengkap sampai tahap ini

Menentukan Pemenang

Sekarang kita sudah menampilkan pemain mana yang akan mendapat giliran selanjutnya, kita juga perlu menampilkan sesuatu ketika permainan sudah dimenangkan oleh salah satu pemain dan tidak ada giliran lagi. Kita dapat menentukan pemenang dengan menambahkan fungsi berikut pada akhir file:

import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';5

Ketika diberi senarai dari kesembilan persegi, fungsi ini akan mengecek pemenang dan cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..04, cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..12, atau cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..13 sesuai dengan hasil.

Kita akan memanggil cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..73 pada fungsi class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9 Board untuk mengecek adanya salah satu pemain yang sudah menang. Jika salah satu pemain sudah menang, kita dapat menampilkan teks seperti “Winner: X” atau “Winner: O”. Kita akan mengganti deklarasi cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..75 pada fungsi class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9 Board dengan kode berikut:

import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';6

Kita dapat mengubah fungsi cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..45 Board untuk kembali lebih awal dengan mengabaikan klik jika salah satu pemain sudah menang atau jika sebuah Square sudah diisi:

import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';7

Lihat kode lengkap sampai tahap ini

Selamat! Anda sekarang sudah memiliki permainan tic-tac-toe yang berjalan dengan baik. Anda juga telah belajar dasar-dasar dari React. Jadi Anda mungkin adalah pemenang yang sebenarnya disini.

Menambahkan Penjelajahan Waktu

Sebagai latihan terakhir, mari kita membuat permainan kita dapat “kembali” ke langkah sebelumnya pada permainan.

Menyimpan Riwayat Langkah

Jika kita melakukan mutate pada senarai cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..14, mengimplementasikan penjelajahan waktu akan sangat sulit.

Tetapi, kita menggunakan cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..79 untuk membuat kopi baru dari senarai cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..14 setelah setiap langkah dan . Hal ini akan membuat kita dapat menyimpan setiap versi sebelumnya dari senarai cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..14 dan melakukan navigasi di antara giliran-giliran yang sudah terjadi.

Kita akan menyimpan riwayat senarai cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..14 pada senarai lain yang bernama cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..83. Senarai cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..83 menggambarkan semua state dari Board dari awal hingga akhir, dan memiliki bentuk seperti ini:

import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';8

Sekarang kita akan menentukan komponen yang akan memiliki state cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..83.

Menaikkan State, Lagi

Kita ingin komponen Game teratas untuk menampilkan riwayat langkah. Untuk melakukan hal tersebut, komponen Game memerlukan akses ke cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..83, sehingga kita akan menempatkan state cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..83 pada komponen teratas Game.

Menempatkan state cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..83 ke komponen Game memungkinkan kita menghapus state cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..14 dari komponen anaknya, komponen Board. Seperti yang kita lakukan pada bagian dari komponen Square ke komponen Board, sekarang kita akan menaikkannya dari Board ke komponen teratas Game. Hal ini memberikan komponen Game kontrol penuh pada data Board dan memungkinkannya untuk memberi instruksi ke Board untuk me-render giliran sebelumnya dari cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..83.

Pertama, mari kita mempersiapkan state awal untuk komponen Game di dalam konstruktornya:

import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';9

Selanjutnya, kita akan membuat komponen Board menerima prop cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..14 dan class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }0 dari komponen Game. Karena sekarang kita sudah memiliki handler untuk klik di dalam Board untuk banyak Square, kita akan perlu memberikan lokasi dari setiap Square ke handler class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }0 untuk memberi tahu Square mana yang diklik. Berikut adalah langkah yang diperlukan untuk mengubah komponen Board:

  • Menghapus class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }7 di Board.
  • Mengganti cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..95 dengan cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..96 pada class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }2 di Board.
  • Mengganti cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..40 dengan cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..99 pada class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }2 di Board.

Sekarang komponen Board akan terlihat seperti ini:

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Daftar Belanja untuk {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Contoh Penggunaan: <ShoppingList name="Mark" />0

Kita akan mengubah fungsi class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9 pada komponen Game agar fungsi tersebut menggunakan entri riwayat terakhir untuk menentukan dan menampilkan status permainan:

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Daftar Belanja untuk {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Contoh Penggunaan: <ShoppingList name="Mark" />1

Karena sekarang komponen Game me-render status permainan, kita dapat menghapus kode yang bersangkutan dari method class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9 Board. Setelah melakukan refactor, fungsi class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9 Board akan terlihat seperti ini:

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Daftar Belanja untuk {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Contoh Penggunaan: <ShoppingList name="Mark" />2

Terakhir, kita perlu memindahkan method cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..45 dari komponen Board ke komponen Game. Kita juga perlu mengubah cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..45 karena state komponen Game memiliki struktur yang berbeda. Di dalam method cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..45 Game, kita menggabungkan (concat) entri riwayat baru ke dalam cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..83.

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Daftar Belanja untuk {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Contoh Penggunaan: <ShoppingList name="Mark" />3

Catatan

Tidak seperti method import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';08 pada senarai, yang mungkin Anda lebih kenal, method import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';09 tidak melakukan mutate pada senarai sebenarnya, jadi kami lebih memilih import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';09.

Sampai tahap ini, komponen Board hanya memerlukan method class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }2 dan class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9. State permainan dan method cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..45 seharusnya ada di dalam komponen Game.

Lihat kode lengkap sampai tahap ini

Menampilakan Langkah-Langkah Sebelumnya

Karena kita merekam riwayat permainan tic-tac-toe, sekarang kita dapat menampilkannya ke pemain sebagai daftar langkah sebelumnya.

Kita mengetahui sebelumnya bahwa elemen React adalah object first-class JavaScript; kita dapat mengoperkannya ke manapun pada aplikasi kita. Untuk me-render banyak elemen React, kita dapat menggunakan senarai berisi elemen React.

Di JavaScript, senarai memiliki method import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';14 yang sering digunakan untuk melakukan pemetaan data ke data lain, contohnya:

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Daftar Belanja untuk {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Contoh Penggunaan: <ShoppingList name="Mark" />4

Dengan menggunakan method import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';15, kita dapat memetakan riwayat langkah kita ke elemen React yang melambangkan tombol pada layar dan menampilkan daftar tombol untuk “melompat” ke langkah sebelumnya.

Mari menerapkan import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';15 pada cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..83 di method class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9 Game:

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Daftar Belanja untuk {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Contoh Penggunaan: <ShoppingList name="Mark" />5

Lihat kode lengkap sampai tahap ini

Untuk setiap langkah pada riwayat permainan tic-tac-toe, kita membuat import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';19 yang berisi class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }1. Tombol (class Square extends React.Component { render() { return ( <button className="square" onClick={function() { alert('click'); }}> {this.props.value} </button> ); } }1) memiliki handler class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }0 yang akan memanggil method bernama import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';23. Kita belum mengimplementasikan method import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';24. Untuk sekarang, kita seharusnya sudah melihat daftar langkah yang sudah terjadi dalam permainan dan peringatan pada developer tools console yang bertuliskan:

Warning: Each child in an array or iterator should have a unique “key” prop. Check the render method of “Game”.

Mari membahas makna dari peringatan tersebut.

Memilih Sebuah Key

Ketika kita me-render sebuah list, React menyimpan informasi tentang setiap elemen dalam list yang di-render. Ketika kita memperbarui sebuah list, React perlu menentukan elemen yang sudah berubah. Kita bisa saja menambahkan, menghapus, mengatur ulang, atau memperbarui elemen pada list.

Bayangkan perubahan dari

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Daftar Belanja untuk {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Contoh Penggunaan: <ShoppingList name="Mark" />6

ke

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Daftar Belanja untuk {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Contoh Penggunaan: <ShoppingList name="Mark" />7

Selain jumlah yang diperbarui, kemampuan baca manusia mungkin akan mengatakan bahwa kita menukar urutan Ben dan Alexa dan menyisipkan Claudia di antara Alexa dan Ben. Tetapi, React adalah program komputer dan tidak tahu intensi kita. Karena React tidak tahu intensi kita, kita perlu memberikan properti key dari setiap elemen pada list untuk membedakan setiap elemen list dari saudaranya (elemen lain dalam satu hirarki). Salah satu opsi adalah dengan menggunakan string import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';25, import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';26, import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';27. Jika kita menampilkan data dari basisdata, ID Alexa, Ben, Claudia pada database dapat digunakan sebagai key.

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Daftar Belanja untuk {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Contoh Penggunaan: <ShoppingList name="Mark" />8

** Ketika list di-render ulang, React mengambil seluruh key dari elemen list dan mencari elemen sebelumnya yang memiliki key yang sama. Jika list saat ini memiliki key yang tidak ada sebelumnya, React akan membuat komponen. Jika list saat ini kehilangan sebuah key yang ada pada list sebelumnya, React menghapus (destroy) komponen sebelumnya. Jika ada dua key yang sama, komponen yang bersangkutan dipindahkan. Key memberi tahu React identitas dari tiap komponen, sehingga membuat React dapat mempertahankan state di setiap render ulang. Jika key dari sebuah komponen berubah, komponen akan dihapus dan dibuat ulang dengan state baru.

import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';28 adalah properti khusus dan sudah dipesan di React (bersama dengan import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';29, fitur yang lebih lanjut). Ketika sebuah elemen dibuat, React mengekstrak properti import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';28 dan menyimpannya langsung ke elemen yang dikembalikan. Walaupun import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';28 terlihat seperti bagian dari class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }7, import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';28 tidak dapat diacu menggunakan import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';34. React menggunakan import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';28 untuk menentukan komponen yang akan diubah secara otomatis. Sebuah komponen tidak dapat menanyakan import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';28 yang dia miliki.

Kami sangat merekomendasikan Anda untuk memberikan key yang baik ketika membuat list dinamik. Jika Anda tidak memiliki key yang baik, Anda dapat mempertimbangkan restukturisasi data Anda sehingga Anda memiliki key yang baik.

Jika tidak ada key yang diberikan, React akan menampilkan sebuah peringatan dan menggunakan indeks senarai sebagai nilai default. Menggunakan indeks senarai bermasalah ketika kita mencoba untuk mengatur ulang elemen list atau menyisipkan/menghapus elemen list. Memberikan import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';37 secara eksplisit menghilangkan peringatannya, tetapi memiliki masalah yang sama, sehingga tidak direkomendasikan pada banyak kasus.

Key tidak perlu unik secara global. Key hanya perlu unik di antara komponen dan saudaranya.

Mengimplementasikan Penjelajahan Waktu

Di dalam riwayat permainan tic-tac-toe, setiap langkah sebelumnya memiliki ID unik yang bersangkutan dengan langkah tersebut: ID tersebut adalah angka terutut yang melambangkan urutan langkah. Riwayat langkah tidak pernah di atur ulang, dihapus, atau disisipi elemen lain di tengah, jadi pada kasus ini kita dapat menggunakan indeks langkah sebagai key.

Dalam method class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9 komponen Game, kita dapat menambahkan key sebagai import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';39 dan peringatan React tentang key akan menghilang:

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Daftar Belanja untuk {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Contoh Penggunaan: <ShoppingList name="Mark" />9

Lihat kode lengkap sampai tahap ini

Mengklik salah satu tombol pada elemen list akan menghasilkan error karena method import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';40 tidak didefinisikan (undefined). Sebelum kita mengimplementasikan import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';40, kita akan menambahkan import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';42 di dalam state komponen Game untuk melambangkan langkah yang sedang kita lihat.

Pertama, tambahkan import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';43 pada state awal di class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }7 Game:

return React.createElement('div', {className: 'shopping-list'}, React.createElement('h1', /* ... h1 children ... */), React.createElement('ul', /* ... ul children ... */) );0

Kemudian, kita akan mendefinisikan method import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';40 di dalam Game untuk memperbarui import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';42. Kita juga dapat membuat cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..66 true jika angka yang kita berikan pada import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';42 adalah genap:

return React.createElement('div', {className: 'shopping-list'}, React.createElement('h1', /* ... h1 children ... */), React.createElement('ul', /* ... ul children ... */) );1

Sekarang kita akan mengubah beberapa bagian method cd my-app cd src # Jika Anda menggunakan Mac atau Linux: rm -f * # Atau jika Anda menggunakan Windows: del * # Kemudian, kembali ke folder project cd ..45 pada Game yang akan dipicu ketika Anda mengklik sebuah persegi.

State import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';42 yang sudah kita tambahkan menggambarkan langkah yang sedang ditampilkan ke pengguna saat ini. Setelah kita membuat langkah baru, kita perlu memperbarui import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';42 dengan menambahkan import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';52 sebagai bagian dari argumen class Square extends React.Component { constructor(props) { super(props); this.state = { value: null, }; } render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }9. Hal ini memastikan kita tidak selalu menampilkan langkah yang sama setelah langkah baru berhasil dibuat.

Kita juga akan mengganti import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';54 dengan import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';55. Hal ini untuk memastikan jika kita “kembali” dan membuat langkah baru dari titik tersebut, kita membuang semua riwayat “masa depan” yang sekarang menjadi tidak benar.

return React.createElement('div', {className: 'shopping-list'}, React.createElement('h1', /* ... h1 children ... */), React.createElement('ul', /* ... ul children ... */) );2

Terakhir, kita dapat mengubah method class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }9 dari komponen Game dari yang selalu me-render langkah terakhir menjadi me-render langkah yang saat ini dipilih berdasarkan import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';42:

return React.createElement('div', {className: 'shopping-list'}, React.createElement('h1', /* ... h1 children ... */), React.createElement('ul', /* ... ul children ... */) );3

Jika kita mengklik salah satu langkah pada riwayat permainan, papan tic-tac-toe seharusnya langsung memperbarui dirinya dan menampilkan papan setelah langkah tersebut dijalankan.

Lihat kode penuh sampai saat ini

Ulasan

Selamat! Anda sudah membuat permainan tic-tac-toe yang:

  • Memungkinkan Anda bermain tic-tac-toe,
  • Memberi tahu pemain yang sudah memenangkan permainan,
  • Menyimpan riwayat permainan selama permainan berlangsung,
  • Memungkinkan pemain untuk mengulas riwayat permainan dan melihat versi sebelumnya dari papan permainan.

Kerja bagus! Kami berharap sekarang Anda merasa Anda memiliki pemahaman yang baik tentang bagaimana React bekerja.

Lihat hasil akhirnya disini: Hasil Akhir.

Jika Anda memiliki waktu luang atau ingin melatih kemampuan baru React Anda, berikut terdapat beberapa ide untuk perbaikan yang dapat Anda aplikasikan pada permainan tic-tac-toe terurut berdasarkan tingkat kesulitan paling mudah ke yang paling sulit:

  1. Menampilkan lokasi dari setiap langkah dalam format (kolom, baris) pada daftar riwayat langkah.
  2. Menebalkan elemen yang sedang dipilih pada daftar langkah.
  3. Menulis ulang Board sehingga menggunakan dua perulangan untuk membuat persegi, bukan melakukan hardcode.
  4. Menambahkan toggle yang memungkinkan Anda untuk mengurutkan langkah terutur membesar atau mengecil.
  5. Ketika salah satu pemain menang, tandai 3 persegi yang membuatnya menang.
  6. Ketika tidak ada yang menang, tampilan pesan bahwa hasilnya seri.

Melalui tutorial ini, kita menyentuh beberapa konsep React termasuk di dalamnya elemen, komponen, props, dan state. Untuk penjelasan lebih rinci dari setiap topik tersebut, kunjungi dokumentasi. Untuk mempelajari lebih lanjut mengenai cara mendefinisikan komponen, kunjungi Referensi API class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }6.

Apa itu react bootstrap?

React Bootstrap adalah framework CSS Bootstrap yang dibagun ulang setiap componentnya dari awal, sehingga tidak memerlukan lagi jQuery di dalamnya. Dan mampu digunakan untuk membangun sebuah user interface dengan ekosistem yang besar.

Apa yang dimaksud dengan bootstrap dan bagaimana cara menggunakannya?

Bootstrap adalah framework front-end gratis yang cukup populer di kalangan developer saat ini, khususnya yang bekerja di bidang desain web. Framework ini mudah digunakan dan membantu developer bekerja lebih cepat tanpa harus menulis kode HTML, CSS, dan JavaScript secara manual.

Bagaimana cara memasang bootstrap?

Download terlebih dahulu file bootstrap melalui laman resminya. ... .
Selanjutnya bukalah teks editor Anda. ... .
Kemudian klik menu File yang ada di bagian toolbar aplikasi Sublime. ... .
Selanjutnya simpanlah file tersebut dengan cara klik menu File lalu pilih menu Save..

Apa itu Bootstrap 5?

Tentang Kelas. Bootstrap adalah sebuah framework yang paling populer digunakan untuk membuat sebuah website. Bootstrap membuat front-end developer dapat membuat website dengan cepat, fokus pada responsive mobile, dan membuat website menjadi lebih interaktif tanpa membuat banyak CSS dan JavaScript dari nol.

Postingan terbaru

LIHAT SEMUA