Apakah reaksi javascript atau html?

Kami akan membuat game kecil selama tutorial ini. Anda mungkin tergoda untuk melewatkannya karena Anda tidak membuat game — tetapi berikan kesempatan. Teknik-teknik yang akan Anda pelajari dalam tutorial merupakan dasar untuk membangun aplikasi React apa pun, dan menguasainya akan memberi Anda pemahaman yang mendalam tentang React

Tip

Tutorial ini dirancang untuk orang yang lebih suka belajar sambil melakukan. Jika Anda lebih suka mempelajari konsep dari awal, lihat panduan langkah demi langkah kami. Anda mungkin menganggap tutorial ini dan panduan ini saling melengkapi

Tutorial ini dibagi menjadi beberapa bagian

  • akan memberi Anda titik awal untuk mengikuti tutorial
  • akan mengajari Anda dasar-dasar React. komponen, props, dan state
  • akan mengajari Anda teknik yang paling umum dalam pengembangan React
  • akan memberi Anda wawasan yang lebih dalam tentang kekuatan unik React

Anda tidak harus menyelesaikan semua bagian sekaligus untuk mendapatkan nilai dari tutorial ini. Cobalah untuk mencapai sejauh yang Anda bisa — meskipun hanya satu atau dua bagian

Apa yang Kita Bangun?

Dalam tutorial ini, kami akan menunjukkan cara membuat game tic-tac-toe interaktif dengan React

Anda dapat melihat apa yang akan kami bangun di sini. Hasil Akhir. Jika kode tidak masuk akal bagi Anda, atau jika Anda tidak terbiasa dengan sintaks kode, jangan khawatir. Tujuan dari tutorial ini adalah untuk membantu Anda memahami React dan sintaksnya

Kami menyarankan Anda memeriksa permainan tic-tac-toe sebelum melanjutkan tutorial. Salah satu fitur yang akan Anda perhatikan adalah adanya daftar bernomor di sebelah kanan papan permainan. Daftar ini memberi Anda riwayat semua gerakan yang telah terjadi dalam gim, dan diperbarui seiring berjalannya gim

Anda dapat menutup permainan tic-tac-toe setelah Anda terbiasa dengannya. Kami akan memulai dari template yang lebih sederhana dalam tutorial ini. Langkah kami selanjutnya adalah menyiapkan Anda agar Anda dapat mulai membuat game

Prasyarat

Kami akan berasumsi bahwa Anda memiliki pengetahuan tentang HTML dan JavaScript, tetapi Anda harus dapat mengikuti bahkan jika Anda berasal dari bahasa pemrograman yang berbeda. Kami juga akan berasumsi bahwa Anda terbiasa dengan konsep pemrograman seperti fungsi, objek, larik, dan pada tingkat yang lebih rendah, kelas

Jika Anda perlu meninjau JavaScript, sebaiknya baca panduan ini. Perhatikan bahwa kami juga menggunakan beberapa fitur dari ES6 — JavaScript versi terbaru. Dalam tutorial ini, kami menggunakan fungsi panah, kelas, pernyataan 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 memeriksa untuk apa kode ES6 dikompilasi

Pengaturan untuk Tutorial

Ada dua cara untuk menyelesaikan tutorial ini. Anda dapat menulis kode di browser Anda, atau Anda dapat menyiapkan lingkungan pengembangan lokal di komputer Anda

Opsi Pengaturan 1. Tulis Kode di Browser

Ini adalah cara tercepat untuk memulai

Pertama, buka Kode Pemula ini di tab baru. Tab baru akan menampilkan papan permainan tic-tac-toe kosong dan kode React. Kami akan mengedit kode React dalam tutorial ini

Anda sekarang dapat melewati opsi pengaturan kedua, dan pergi ke bagian untuk mendapatkan gambaran umum tentang React

Opsi Pengaturan 2. Lingkungan Pembangunan Lokal

Ini sepenuhnya opsional dan tidak diperlukan untuk tutorial ini


Opsional. Petunjuk untuk mengikuti secara lokal menggunakan editor teks pilihan Anda

Penyiapan ini membutuhkan lebih banyak pekerjaan tetapi memungkinkan Anda menyelesaikan tutorial menggunakan editor pilihan Anda. Berikut langkah-langkah yang harus diikuti

  1. Pastikan Anda memiliki Node versi terbaru. js diinstal
  2. Ikuti untuk membuat proyek baru

npx create-react-app my-app

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

Catatan

Jangan hapus seluruh folder return React.createElement('div', {className: 'shopping-list'}, React.createElement('h1', /* .. h1 children .. */), React.createElement('ul', /* .. ul children .. */) );_7, hanya file sumber asli di dalamnya. Kami akan mengganti file sumber default dengan contoh untuk proyek ini di langkah berikutnya

cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..

  1. Tambahkan file bernama return React.createElement('div', {className: 'shopping-list'}, React.createElement('h1', /* .. h1 children .. */), React.createElement('ul', /* .. ul children .. */) );_8 di 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 di 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 ini ke bagian atas class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }_0 di 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/client'; import './index.css';

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

Kami merekomendasikan mengikuti petunjuk ini untuk mengonfigurasi penyorotan sintaks untuk editor Anda

Tolong, saya Terjebak

Jika Anda buntu, periksa sumber daya dukungan komunitas. Secara khusus, Obrolan Reactilux adalah cara yang bagus untuk mendapatkan bantuan dengan cepat. Jika Anda tidak menerima jawaban, atau jika Anda tetap buntu, ajukan masalah, dan kami akan membantu Anda

Ringkasan

Sekarang setelah Anda siap, mari dapatkan ikhtisar tentang React

Apa itu Bereaksi?

React adalah pustaka JavaScript yang deklaratif, efisien, dan fleksibel untuk membangun antarmuka pengguna. Ini memungkinkan Anda membuat UI kompleks dari potongan kode kecil dan terisolasi yang disebut "komponen"

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

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Shopping List for {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Example usage: <ShoppingList name="Mark" />

Kami akan segera membahas tag mirip XML yang lucu. Kami menggunakan komponen untuk memberi tahu React apa yang ingin kami lihat di layar. Saat data kita berubah, React akan memperbarui dan merender ulang komponen kita secara efisien

Di sini, ShoppingList adalah kelas komponen React, atau tipe komponen React. Komponen mengambil parameter, disebut class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }_7 (singkatan dari "properti"), dan mengembalikan hierarki tampilan untuk ditampilkan melalui metode class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }8

Metode class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }8 mengembalikan deskripsi tentang apa yang ingin Anda lihat di layar. React mengambil deskripsi dan menampilkan hasilnya. Secara khusus, class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }_8 mengembalikan elemen React, yang merupakan deskripsi ringan tentang apa yang akan dirender. Sebagian besar pengembang React menggunakan sintaks khusus yang disebut "JSX" yang membuat struktur ini lebih mudah untuk ditulis. Sintaks class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }1 diubah pada waktu pembuatan menjadi class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }2. Contoh di atas setara dengan

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> ); } }_3 dijelaskan lebih detail di , tetapi kami tidak akan menggunakannya dalam tutorial ini. Sebagai gantinya, kami akan tetap menggunakan JSX

JSX hadir dengan kekuatan penuh JavaScript. Anda dapat menempatkan ekspresi JavaScript apa pun di dalam kurung kurawal di dalam JSX. Setiap elemen React adalah objek JavaScript yang dapat Anda simpan dalam variabel atau bagikan dalam program Anda

Komponen class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }_4 di atas hanya merender komponen DOM bawaan seperti class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }1 dan class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }6. Tapi Anda juga bisa membuat dan merender komponen React kustom. Misalnya, kita sekarang dapat merujuk ke seluruh daftar belanja dengan menulis class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }7. Setiap komponen React dienkapsulasi dan dapat beroperasi secara independen;

Memeriksa Kode Pemula

Jika Anda akan mengerjakan tutorial di browser Anda, buka kode ini di tab baru. Kode Pemula. Jika Anda akan mengerjakan tutorial secara lokal, buka class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }8 di folder proyek Anda (Anda telah menyentuh file ini selama )

Kode Pemula ini adalah dasar dari apa yang kami buat. Kami telah menyediakan gaya CSS sehingga Anda hanya perlu fokus mempelajari React dan memprogram game tic-tac-toe

Dengan memeriksa kodenya, Anda akan melihat bahwa kami memiliki tiga komponen React

  • Persegi
  • Papan
  • Permainan

Komponen Kotak membuat class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }9 tunggal dan Papan membuat 9 kotak. Komponen Game merender papan dengan nilai placeholder yang akan kita ubah nanti. Saat ini tidak ada komponen interaktif

Melewati Data Melalui Alat Peraga

Agar kaki kita basah, mari kita coba meneruskan beberapa data dari komponen Board kita ke komponen Square kita

Kami sangat menyarankan mengetik kode dengan tangan saat Anda mengerjakan tutorial dan tidak menggunakan copy/paste. Ini akan membantu Anda mengembangkan memori otot dan pemahaman yang lebih kuat

Dalam metode class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }0 Board, ubah kode untuk meneruskan prop yang disebut class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }1 ke Square

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

Ubah metode class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }_8 Square untuk menunjukkan nilai tersebut dengan mengganti class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }3 dengan class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }4

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

Sebelum

Setelah. Anda akan melihat angka di setiap kotak dalam output yang diberikan

Lihat kode lengkapnya pada saat ini

Selamat. Anda baru saja "menyerahkan prop" dari komponen Board induk ke komponen Square anak. Meneruskan props adalah bagaimana informasi mengalir di aplikasi React, dari orang tua ke anak

Membuat Komponen Interaktif

Mari isi komponen Kotak dengan "X" saat kita mengkliknya. Pertama, ubah tag tombol yang dikembalikan dari fungsi class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }5 komponen Square menjadi ini

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

Jika Anda mengklik Kotak sekarang, Anda akan melihat 'klik' di konsol devtools browser Anda

Catatan

Untuk menyimpan pengetikan dan menghindari perilaku membingungkan class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }6, kami akan menggunakan sintaks fungsi panah untuk penangan acara di sini dan selanjutnya di bawah

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

Perhatikan bagaimana dengan class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }_7, kami meneruskan fungsi sebagai prop class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }8. Bereaksi hanya akan memanggil fungsi ini setelah klik. Melupakan class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }9 dan menulis class Square extends React.Component { render() { return ( <button className="square" onClick={() => console.log('click')}> {this.props.value} </button> ); } }0 adalah kesalahan umum, dan akan diaktifkan setiap kali komponen dirender ulang

Sebagai langkah selanjutnya, kami ingin komponen Kotak "mengingat" bahwa komponen itu diklik, dan mengisinya dengan tanda "X". Untuk "mengingat" sesuatu, komponen menggunakan status

Bereaksi komponen dapat memiliki status dengan menyetel class Square extends React.Component { render() { return ( <button className="square" onClick={() => console.log('click')}> {this.props.value} </button> ); } }1 di konstruktornya. class Square extends React.Component { render() { return ( <button className="square" onClick={() => console.log('click')}> {this.props.value} </button> ); } }_1 harus dianggap sebagai pribadi untuk komponen React yang didefinisikan di dalamnya. Mari simpan nilai Kotak saat ini di class Square extends React.Component { render() { return ( <button className="square" onClick={() => console.log('click')}> {this.props.value} </button> ); } }1, dan ubah saat Kotak diklik

Pertama, kami akan menambahkan konstruktor ke kelas untuk menginisialisasi status

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

Catatan

Di kelas JavaScript, Anda harus selalu memanggil class Square extends React.Component { render() { return ( <button className="square" onClick={() => console.log('click')}> {this.props.value} </button> ); } }4 saat menentukan konstruktor subkelas. Semua kelas komponen React yang memiliki class Square extends React.Component { render() { return ( <button className="square" onClick={() => console.log('click')}> {this.props.value} </button> ); } }5 harus dimulai dengan panggilan class Square extends React.Component { render() { return ( <button className="square" onClick={() => console.log('click')}> {this.props.value} </button> ); } }6

Sekarang kita akan mengubah metode ________8______8 Square untuk menampilkan nilai keadaan saat ini saat diklik

  • Ganti class Square extends React.Component { render() { return ( <button className="square" onClick={() => console.log('click')}> {this.props.value} </button> ); } }8 dengan class Square extends React.Component { render() { return ( <button className="square" onClick={() => console.log('click')}> {this.props.value} </button> ); } }9 di dalam tag class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }9
  • Ganti event handler class Square extends React.Component { constructor(props) { super(props); this.state = { value: null, }; } render() { return ( <button className="square" onClick={() => console.log('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={() => console.log('click')}> {this.props.value} </button> ); } }2
  • Letakkan class Square extends React.Component { constructor(props) { super(props); this.state = { value: null, }; } render() { return ( <button className="square" onClick={() => console.log('click')}> {this.props.value} </button> ); } }3 dan class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }8 alat peraga pada baris terpisah untuk keterbacaan yang lebih baik

Setelah perubahan ini, tag class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }9 yang dikembalikan oleh metode Square class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }8 terlihat seperti ini

cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..0

Dengan memanggil class Square extends React.Component { constructor(props) { super(props); this.state = { value: null, }; } render() { return ( <button className="square" onClick={() => console.log('click')}> {this.props.value} </button> ); } }7 dari handler class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }8 dalam metode class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }8 Square, kita memberi tahu React untuk merender ulang Square itu setiap kali class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }9 diklik. Setelah pembaruan, class Square extends React.Component { render() { return ( <button className="square" onClick={() => console.log('click')}> {this.props.value} </button> ); } }_9 Square akan menjadi cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..02, jadi kita akan melihat cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..03 di papan permainan. Jika Anda mengeklik Kotak mana pun, cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._03 akan muncul

Saat Anda memanggil cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..05 dalam sebuah komponen, React juga secara otomatis memperbarui komponen anak di dalamnya

Lihat kode lengkapnya pada saat ini

Alat pengembang

Ekstensi React Devtools untuk Chrome dan Firefox memungkinkan Anda memeriksa pohon komponen React dengan alat pengembang browser Anda

React DevTools memungkinkan Anda memeriksa properti dan status komponen React Anda

Setelah menginstal React DevTools, Anda dapat mengeklik kanan elemen apa pun di halaman, klik "Periksa" untuk membuka alat pengembang, dan tab React ("⚛️ Komponen" dan "⚛️ Profiler") akan muncul sebagai tab terakhir ke . Gunakan “⚛️ Komponen” untuk memeriksa pohon komponen

Namun, perhatikan ada beberapa langkah tambahan untuk membuatnya berfungsi dengan CodePen

  1. Masuk atau daftar dan konfirmasi email Anda (diperlukan untuk mencegah spam)
  2. Klik tombol "Garpu".
  3. Klik "Ubah Tampilan" dan kemudian pilih "Mode debug"
  4. Di tab baru yang terbuka, devtools seharusnya sudah memiliki tab React

Menyelesaikan Permainan

Kami sekarang memiliki blok bangunan dasar untuk permainan tic-tac-toe kami. Untuk memiliki permainan yang lengkap, sekarang kita perlu menempatkan "X" dan "O" secara bergantian di papan, dan kita memerlukan cara untuk menentukan pemenang

Mengangkat Status

Saat ini, setiap komponen Kotak mempertahankan status permainan. Untuk memeriksa pemenang, kami akan mempertahankan nilai masing-masing dari 9 kotak di satu lokasi

Kami mungkin berpikir bahwa Dewan seharusnya hanya meminta setiap Kotak untuk status Kotak. Meskipun pendekatan ini dimungkinkan di React, kami tidak menyarankannya karena kodenya menjadi sulit dipahami, rentan terhadap bug, dan sulit untuk di-refactor. Alih-alih, pendekatan terbaik adalah menyimpan status game di komponen Papan induk alih-alih di setiap Kotak. Komponen Papan dapat memberi tahu setiap Kotak apa yang harus ditampilkan dengan memberikan penyangga,

Untuk mengumpulkan data dari beberapa turunan, atau agar dua komponen turunan saling berkomunikasi, Anda perlu mendeklarasikan status bersama di komponen induknya. Komponen induk dapat meneruskan status kembali ke anak-anak dengan menggunakan alat peraga;

Mengangkat status ke dalam komponen induk adalah hal biasa ketika komponen React difaktorkan ulang — mari gunakan kesempatan ini untuk mencobanya

Tambahkan konstruktor ke Papan dan atur status awal Papan agar berisi larik 9 nol yang sesuai dengan 9 kotak

cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..1

Saat kita mengisi papan nanti, larik cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..06 akan terlihat seperti ini

cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..2

Metode Dewan class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }_0 saat ini terlihat seperti ini

cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._3

Pada awalnya, kami dari Papan menunjukkan angka dari 0 hingga 8 di setiap Kotak. Pada langkah sebelumnya yang berbeda, kami mengganti angka dengan tanda “X”. Inilah mengapa Square saat ini mengabaikan prop class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }1 yang diteruskan oleh Dewan

Kami sekarang akan menggunakan mekanisme prop passing lagi. Kami akan memodifikasi Papan untuk menginstruksikan setiap Kotak individu tentang nilainya saat ini (cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..02, cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..11, atau cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..12). Kami telah mendefinisikan array cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..13 di konstruktor Board, dan kami akan memodifikasi metode class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }0 Board untuk membacanya

cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._4

Lihat kode lengkapnya pada saat ini

Setiap Kotak sekarang akan menerima penyangga class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }_1 yang akan menjadi cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..02, cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..11, atau cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..12 untuk kotak kosong

Selanjutnya, kita perlu mengubah apa yang terjadi saat Kotak diklik. Komponen Dewan sekarang mempertahankan kotak mana yang diisi. Kita perlu membuat cara agar Square memperbarui status Dewan. Karena status dianggap pribadi untuk komponen yang mendefinisikannya, kami tidak dapat memperbarui status Dewan secara langsung dari Kotak

Sebagai gantinya, kami akan meneruskan fungsi dari Papan ke Kotak, dan kami akan membuat Kotak memanggil fungsi tersebut saat kotak diklik. Kami akan mengubah metode class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }_0 di Board menjadi

cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..5

Catatan

Kami membagi elemen yang dikembalikan menjadi beberapa baris agar mudah dibaca, dan menambahkan tanda kurung sehingga JavaScript tidak menyisipkan titik koma setelah cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..20 dan merusak kode kami

Sekarang kami memberikan dua properti dari Board ke Square. class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }1 dan class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }8. Prop class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }_8 adalah fungsi yang dapat dipanggil Square saat diklik. Kami akan membuat perubahan berikut pada Kotak

  • Ganti class Square extends React.Component { render() { return ( <button className="square" onClick={() => console.log('click')}> {this.props.value} </button> ); } }_9 dengan class Square extends React.Component { render() { return ( <button className="square" onClick={() => console.log('click')}> {this.props.value} </button> ); } }8 dalam metode Square class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }8
  • Ganti cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._27 dengan cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..28 dalam metode class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }8 Square
  • Hapus class Square extends React.Component { render() { return ( <button className="square" onClick={() => console.log('click')}> {this.props.value} </button> ); } }_5 dari Kotak karena Kotak tidak lagi melacak status permainan

Setelah perubahan ini, komponen Kotak terlihat seperti ini

cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._6

Saat Kotak diklik, fungsi class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }8 yang disediakan oleh Papan akan dipanggil. Berikut ulasan tentang bagaimana hal ini dicapai

  1. Prop class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }_8 pada komponen DOM class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }9 bawaan memberi tahu React untuk menyiapkan click event listener
  2. Saat tombol diklik, React akan memanggil event handler class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }8 yang didefinisikan dalam metode class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }5 Square
  3. Event handler ini memanggil cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._28. Prop class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }_8 Square ditentukan oleh Dewan
  4. Karena Papan melewati cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..38 ke Kotak, Kotak memanggil cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..39 Papan saat diklik
  5. Kami belum mendefinisikan metode cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._40, jadi kode kami mogok. Jika Anda mengeklik kotak sekarang, Anda akan melihat layar kesalahan berwarna merah yang mengatakan sesuatu seperti “ini. handleClick bukan fungsi”

Catatan

Atribut class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }9 elemen DOM class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }8 memiliki arti khusus untuk Bereaksi karena merupakan komponen bawaan. Untuk komponen khusus seperti Kotak, penamaannya terserah Anda. Kita dapat memberi nama apa saja pada prop class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }8 Square atau metode cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..44 milik Dewan, dan kodenya akan bekerja sama. Di React, menggunakan nama cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..45 untuk props yang mewakili event dan cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..46 untuk metode yang menangani event adalah hal yang konvensional.

Saat kami mencoba mengklik Kotak, kami akan mendapatkan kesalahan karena kami belum menentukan cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..44. Kami sekarang akan menambahkan cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._44 ke kelas Dewan

cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._7

Lihat kode lengkapnya pada saat ini

Setelah perubahan ini, kami kembali dapat mengklik Kotak untuk mengisinya, sama seperti sebelumnya. Namun, sekarang status disimpan dalam komponen Board, bukan di komponen Square individual. Saat status Papan berubah, komponen Kotak akan dirender ulang secara otomatis. Menjaga status semua kotak di komponen Papan akan memungkinkannya menentukan pemenang di masa mendatang

Karena komponen Kotak tidak lagi mempertahankan keadaan, komponen Kotak menerima nilai dari komponen Papan dan menginformasikan komponen Papan saat diklik. Dalam istilah React, komponen Square sekarang adalah komponen yang dikontrol. Dewan memiliki kendali penuh atas mereka

Perhatikan bagaimana di cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._44, kami memanggil cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..50 untuk membuat salinan larik cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..13 untuk diubah alih-alih memodifikasi larik yang ada. Kami akan menjelaskan mengapa kami membuat salinan larik cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..13 di bagian berikutnya

Mengapa Kekekalan Itu Penting

Dalam contoh kode sebelumnya, kami menyarankan agar Anda membuat salinan larik cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..13 menggunakan metode cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..54 alih-alih memodifikasi larik yang ada. Sekarang kita akan membahas kekekalan dan mengapa kekekalan penting untuk dipelajari

Biasanya ada dua pendekatan untuk mengubah data. Pendekatan pertama adalah memutasi data dengan langsung mengubah nilai data. Pendekatan kedua adalah mengganti data dengan salinan baru yang memiliki perubahan yang diinginkan

Perubahan Data dengan Mutasi

cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._8

Perubahan Data Tanpa Mutasi

cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._9

Hasil akhirnya sama tetapi dengan tidak memutasikan (atau mengubah data yang mendasarinya) secara langsung, kita mendapatkan beberapa keuntungan yang dijelaskan di bawah ini

Fitur Kompleks Menjadi Sederhana

Kekekalan membuat fitur kompleks lebih mudah diimplementasikan. Nanti dalam tutorial ini, kami akan menerapkan fitur "perjalanan waktu" yang memungkinkan kami meninjau riwayat permainan tic-tac-toe dan "melompat kembali" ke gerakan sebelumnya. Fungsionalitas ini tidak khusus untuk game — kemampuan untuk membatalkan dan mengulangi tindakan tertentu merupakan persyaratan umum dalam aplikasi. Menghindari mutasi data langsung memungkinkan kami menjaga versi riwayat game sebelumnya tetap utuh, dan menggunakannya kembali nanti

Mendeteksi Perubahan

Mendeteksi perubahan pada objek yang bisa berubah itu sulit karena dimodifikasi secara langsung. Deteksi ini membutuhkan objek yang dapat diubah untuk dibandingkan dengan salinan dirinya sendiri sebelumnya dan seluruh pohon objek untuk dilalui

Mendeteksi perubahan pada objek yang tidak dapat diubah jauh lebih mudah. Jika objek tetap yang direferensikan berbeda dari yang sebelumnya, maka objek tersebut telah berubah

Menentukan Kapan Re-Render di React

Manfaat utama kekekalan adalah membantu Anda membuat komponen murni di React. Data yang tidak dapat diubah dapat dengan mudah menentukan apakah perubahan telah dilakukan, yang membantu menentukan kapan suatu komponen perlu dirender ulang

Anda dapat mempelajari lebih lanjut tentang cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..55 dan bagaimana Anda dapat membuat komponen murni dengan membaca

Komponen Fungsi

Kami sekarang akan mengubah Kotak menjadi komponen fungsi

Di React, komponen fungsi adalah cara yang lebih sederhana untuk menulis komponen yang hanya berisi metode class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }8 dan tidak memiliki statusnya sendiri. Alih-alih mendefinisikan kelas yang memperluas class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }6, kita dapat menulis fungsi yang mengambil class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }7 sebagai input dan mengembalikan apa yang harus dirender. Komponen fungsi tidak terlalu membosankan untuk ditulis dibandingkan kelas, dan banyak komponen dapat diekspresikan dengan cara ini

Ganti kelas Square dengan fungsi ini

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

Kami telah mengubah cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..59 menjadi class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }7 kedua kali muncul

Lihat kode lengkapnya pada saat ini

Catatan

Saat kami memodifikasi Kotak menjadi komponen fungsi, kami juga mengubah cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..61 menjadi cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..62 yang lebih pendek (perhatikan kurangnya tanda kurung di kedua sisi)

Bergiliran

Kami sekarang perlu memperbaiki cacat yang jelas dalam permainan tic-tac-toe kami. huruf “O” tidak dapat ditandai di papan tulis

Kami akan menetapkan langkah pertama menjadi "X" secara default. Kita dapat menyetel default ini dengan memodifikasi status awal di konstruktor Board kita

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

Setiap kali pemain bergerak, cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._63 (boolean) akan dibalik untuk menentukan pemain mana yang pergi berikutnya dan status permainan akan disimpan. Kami akan memperbarui fungsi cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._44 Dewan untuk membalikkan nilai cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..63

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

Dengan perubahan ini, “X” dan “O” dapat bergiliran. Cobalah

Mari kita juga mengubah teks "status" di Board class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }8 sehingga menampilkan pemain mana yang mendapat giliran berikutnya

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

Setelah menerapkan perubahan ini, Anda akan memiliki komponen Board ini

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

Lihat kode lengkapnya pada saat ini

Menyatakan Pemenang

Sekarang kami menunjukkan giliran pemain mana yang berikutnya, kami juga harus menunjukkan kapan permainan dimenangkan dan tidak ada lagi giliran yang harus dilakukan. Salin fungsi pembantu ini dan tempel di akhir file

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

Diberikan array 9 kotak, fungsi ini akan memeriksa pemenang dan mengembalikan cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..02, cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..11, atau cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..12 sebagaimana mestinya

Kami akan memanggil cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._70 di fungsi Dewan class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }8 untuk memeriksa apakah seorang pemain telah menang. Jika seorang pemain menang, kami dapat menampilkan teks seperti “Pemenang. X” atau “Pemenang. HAI". Kami akan mengganti deklarasi cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..72 dalam fungsi class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }8 Dewan dengan kode ini

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

Kami sekarang dapat mengubah fungsi cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._44 Papan untuk kembali lebih awal dengan mengabaikan klik jika seseorang telah memenangkan permainan atau jika Kotak sudah terisi

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

Lihat kode lengkapnya pada saat ini

Selamat. Anda sekarang memiliki permainan tic-tac-toe yang berfungsi. Dan Anda juga baru saja mempelajari dasar-dasar React. Jadi Anda mungkin adalah pemenang sebenarnya di sini

Menambahkan Perjalanan Waktu

Sebagai latihan terakhir, mari kita buat "kembali ke masa lalu" ke gerakan sebelumnya dalam permainan

Menyimpan Sejarah Gerakan

Jika kita mengubah larik cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._13, mengimplementasikan perjalanan waktu akan sangat sulit

Namun, kami menggunakan cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..54 untuk membuat salinan baru dari larik cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..13 setelah setiap gerakan, dan. Ini akan memungkinkan kita untuk menyimpan setiap versi terakhir dari larik cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..13, dan menavigasi di antara belokan yang telah terjadi

Kami akan menyimpan array cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._13 sebelumnya dalam array lain yang disebut cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..80. Array cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._80 mewakili semua status papan, dari langkah pertama hingga terakhir, dan memiliki bentuk seperti ini

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

Sekarang kita perlu memutuskan komponen mana yang harus memiliki status cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..80

Mengangkat Status, Lagi

Kami ingin komponen Game tingkat atas menampilkan daftar gerakan sebelumnya. Ini akan memerlukan akses ke cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._80 untuk melakukan itu, jadi kami akan menempatkan status cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..80 di komponen Game tingkat atas

Menempatkan status cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._80 ke dalam komponen Game memungkinkan kita menghapus status cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..13 dari komponen Papan turunannya. Sama seperti kita dari komponen Kotak ke dalam komponen Papan, kita sekarang mengangkatnya dari Papan ke komponen Game tingkat atas. Ini memberi komponen Game kontrol penuh atas data Papan, dan memungkinkannya menginstruksikan Papan untuk membuat giliran sebelumnya dari cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..80

Pertama, kita akan menyiapkan status awal untuk komponen Game di dalam konstruktornya

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

Selanjutnya, kita akan membuat komponen Board menerima cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..13 dan class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }8 props dari komponen Game. Karena kita sekarang memiliki penangan klik tunggal di Papan untuk banyak Kotak, kita harus meneruskan lokasi setiap Kotak ke penangan class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }8 untuk menunjukkan Kotak mana yang diklik. Berikut adalah langkah-langkah yang diperlukan untuk mengubah komponen Board

  • Hapus class Square extends React.Component { render() { return ( <button className="square" onClick={() => console.log('click')}> {this.props.value} </button> ); } }_5 di Papan
  • Ganti cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._92 dengan cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..93 di Dewan class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }0
  • Ganti cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._95 dengan cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..96 di Dewan class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }0

Komponen Dewan sekarang terlihat seperti ini

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Shopping List for {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Example usage: <ShoppingList name="Mark" />_0

Kami akan memperbarui fungsi ________8______8 komponen Game untuk menggunakan entri riwayat terbaru untuk menentukan dan menampilkan status game

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Shopping List for {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Example usage: <ShoppingList name="Mark" />_1

Karena komponen Game sekarang merender status game, kami dapat menghapus kode yang sesuai dari metode class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }8 Dewan. Setelah pemfaktoran ulang, fungsi ________8______8 Dewan terlihat seperti ini

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Shopping List for {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Example usage: <ShoppingList name="Mark" />_2

Terakhir, kita perlu memindahkan metode cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._44 dari komponen Board ke komponen Game. Kita juga perlu memodifikasi cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..44 karena status komponen Game disusun secara berbeda. Dalam metode cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..44 Game, kami menggabungkan entri riwayat baru ke cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..80

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Shopping List for {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Example usage: <ShoppingList name="Mark" />_3

Catatan

Tidak seperti metode array import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';05 yang mungkin lebih Anda kenal, metode import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';06 tidak mengubah array asli, jadi kami lebih memilihnya

Pada titik ini, komponen Dewan hanya memerlukan metode class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }0 dan class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }8. Status game dan metode cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._44 harus ada dalam komponen Game

Lihat kode lengkapnya pada saat ini

Menampilkan Gerakan Masa Lalu

Karena kami merekam sejarah permainan tic-tac-toe, sekarang kami dapat menampilkannya kepada pemain sebagai daftar gerakan sebelumnya

Kita telah mempelajari sebelumnya bahwa elemen React adalah objek JavaScript kelas satu; . Untuk merender beberapa item dalam React, kita dapat menggunakan larik elemen React

Dalam JavaScript, array memiliki metode import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';_10 yang biasa digunakan untuk memetakan data ke data lain, misalnya

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Shopping List for {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Example usage: <ShoppingList name="Mark" />_4

Dengan menggunakan metode import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';_11, kita dapat memetakan riwayat perpindahan kita ke elemen React yang mewakili tombol di layar, dan menampilkan daftar tombol untuk "melompat" ke gerakan sebelumnya

Ayo import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';11 melalui cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..80 dalam metode class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }8 Game

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Shopping List for {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Example usage: <ShoppingList name="Mark" />_5

Lihat kode lengkapnya pada saat ini

Saat kita mengulangi array cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd .._80, variabel import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';16 mengacu pada nilai elemen cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..80 saat ini, dan import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';18 merujuk pada indeks elemen cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..80 saat ini. Kami hanya tertarik pada import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';_18 di sini, karenanya import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';16 tidak ditugaskan untuk apa pun

Untuk setiap gerakan dalam riwayat permainan tic-tac-toe, kami membuat item daftar import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';22 yang berisi tombol class Square extends React.Component { render() { return ( <button className="square"> {this.props.value} </button> ); } }9. Tombol memiliki penangan class Square extends React.Component { render() { return ( <button className="square" onClick={function() { console.log('click'); }}> {this.props.value} </button> ); } }8 yang memanggil metode yang disebut import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';25. Kami belum menerapkan metode import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';26. Untuk saat ini, kita akan melihat daftar gerakan yang telah terjadi dalam game dan peringatan di konsol alat pengembang yang berbunyi

Peringatan. Setiap anak dalam larik atau iterator harus memiliki prop "kunci" yang unik. Periksa metode render "Game"

Mari kita bahas apa arti peringatan di atas

Memilih Kunci

Saat kita merender daftar, React menyimpan beberapa informasi tentang setiap item daftar yang dirender. Saat kami memperbarui daftar, React perlu menentukan apa yang telah berubah. Kami dapat menambahkan, menghapus, mengatur ulang, atau memperbarui item daftar

Bayangkan transisi dari

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Shopping List for {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Example usage: <ShoppingList name="Mark" />_6

ke

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Shopping List for {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Example usage: <ShoppingList name="Mark" />_7

Selain jumlah yang diperbarui, manusia yang membaca ini mungkin akan mengatakan bahwa kami menukar pesanan Alexa dan Ben dan memasukkan Claudia di antara Alexa dan Ben. Namun, Bereaksi adalah program komputer dan tidak tahu apa yang kami maksudkan. Karena React tidak dapat mengetahui maksud kita, kita perlu menentukan properti key untuk setiap item daftar untuk membedakan setiap item daftar dari saudara kandungnya. Salah satu opsi adalah menggunakan string import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';27, import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';28, import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';29. Jika kami menampilkan data dari database, ID database Alexa, Ben, dan Claudia dapat digunakan sebagai kunci

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Shopping List for {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Example usage: <ShoppingList name="Mark" />_8

Ketika daftar dirender ulang, React mengambil kunci setiap item daftar dan mencari item daftar sebelumnya untuk kunci yang cocok. Jika daftar saat ini memiliki kunci yang sebelumnya tidak ada, React membuat sebuah komponen. Jika daftar saat ini kehilangan kunci yang ada di daftar sebelumnya, React akan menghapus komponen sebelumnya. Jika dua tombol cocok, komponen yang sesuai akan dipindahkan. Kunci memberi tahu React tentang identitas setiap komponen yang memungkinkan React mempertahankan status di antara render ulang. Jika kunci komponen berubah, komponen akan dihancurkan dan dibuat ulang dengan status baru

import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';30 adalah properti khusus dan dicadangkan di React (bersama dengan import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';31, fitur yang lebih canggih). Ketika sebuah elemen dibuat, React mengekstrak properti import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';30 dan menyimpan kunci langsung pada elemen yang dikembalikan. Meskipun import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';_30 mungkin terlihat seperti milik class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }7, import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';30 tidak dapat dirujuk menggunakan import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';36. Bereaksi secara otomatis menggunakan import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';_30 untuk memutuskan komponen mana yang akan diperbarui. Sebuah komponen tidak dapat menanyakan tentang ________12______30

Sangat disarankan agar Anda menetapkan kunci yang tepat setiap kali membuat daftar dinamis. Jika Anda tidak memiliki kunci yang sesuai, Anda mungkin ingin mempertimbangkan untuk merestrukturisasi data Anda sehingga Anda memilikinya

Jika tidak ada kunci yang ditentukan, React akan memberikan peringatan dan menggunakan indeks array sebagai kunci secara default. Menggunakan indeks array sebagai kunci bermasalah saat mencoba mengurutkan ulang item daftar atau memasukkan/menghapus item daftar. Melewati import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';_39 secara eksplisit membungkam peringatan tetapi memiliki masalah yang sama dengan indeks array dan tidak direkomendasikan dalam banyak kasus

Kunci tidak harus unik secara global;

Menerapkan Perjalanan Waktu

Dalam sejarah permainan tic-tac-toe, setiap langkah sebelumnya memiliki ID unik yang terkait dengannya. itu adalah nomor urut dari langkah tersebut. Gerakan tidak pernah diurutkan ulang, dihapus, atau disisipkan di tengah, jadi aman menggunakan indeks gerakan sebagai kunci

Dalam metode class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }8 komponen Game, kita dapat menambahkan kunci sebagai import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';41 dan peringatan React tentang kunci akan hilang

class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Shopping List for {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Example usage: <ShoppingList name="Mark" />_9

Lihat kode lengkapnya pada saat ini

Mengklik salah satu tombol item daftar menimbulkan kesalahan karena metode ________12______42 tidak ditentukan. Sebelum kami menerapkan import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';42, kami akan menambahkan import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';44 ke status komponen Game untuk menunjukkan langkah mana yang sedang kami lihat

Pertama, tambahkan import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';_45 ke status awal di class Square extends React.Component { render() { return ( <button className="square" onClick={() => console.log('click')}> {this.props.value} </button> ); } }5 Game

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

Selanjutnya, kita akan menentukan metode import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';_42 di Game untuk memperbarui import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';44 itu. Kita juga menyetel cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..63 menjadi true jika angka yang kita ubah import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';44 menjadi genap

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

Pemberitahuan dalam metode import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';_42, kami belum memperbarui cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..80 milik negara. Itu karena pembaruan status digabungkan atau dengan kata yang lebih sederhana React hanya akan memperbarui properti yang disebutkan dalam metode cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..05 meninggalkan status yang tersisa apa adanya. Untuk info lebih lanjut

Kami sekarang akan membuat beberapa perubahan pada metode cd my-app cd src # If you're using a Mac or Linux: rm -f * # Or, if you're on Windows: del * # Then, switch back to the project folder cd ..44 Game yang aktif saat Anda mengeklik kotak

Status import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';_44 yang telah kami tambahkan mencerminkan langkah yang ditampilkan kepada pengguna sekarang. Setelah kita melakukan langkah baru, kita perlu memperbarui import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';44 dengan menambahkan import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';57 sebagai bagian dari argumen class Square extends React.Component { constructor(props) { super(props); this.state = { value: null, }; } render() { return ( <button className="square" onClick={() => console.log('click')}> {this.props.value} </button> ); } }7. Ini memastikan kami tidak terjebak menunjukkan langkah yang sama setelah yang baru dibuat

Kami juga akan mengganti bacaan import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';_59 dengan import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';60. Ini memastikan bahwa jika kita "kembali ke masa lalu" dan kemudian mengambil langkah baru dari titik itu, kita membuang semua sejarah "masa depan" yang sekarang salah.

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

Terakhir, kami akan mengubah metode class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }8 komponen Game dari selalu merender langkah terakhir menjadi merender langkah yang saat ini dipilih sesuai dengan import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css';44

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

Jika kita mengklik salah satu langkah dalam riwayat permainan, papan tic-tac-toe akan segera diperbarui untuk menunjukkan tampilan papan setelah langkah tersebut terjadi

Lihat kode lengkapnya pada saat ini

Membungkus

Selamat. Anda telah membuat game tic-tac-toe itu

  • Memungkinkan Anda bermain tic-tac-toe,
  • Menunjukkan ketika seorang pemain telah memenangkan permainan,
  • Menyimpan riwayat game saat game berlangsung,
  • Mengizinkan pemain meninjau riwayat game dan melihat papan game versi sebelumnya

Kerja bagus. Kami harap Anda sekarang merasa memiliki pemahaman yang baik tentang cara kerja React

Lihat hasil akhirnya di sini. Hasil Akhir

Jika Anda memiliki waktu ekstra atau ingin melatih keterampilan Bereaksi baru Anda, berikut adalah beberapa ide untuk peningkatan yang dapat Anda lakukan pada permainan tic-tac-toe yang dicantumkan dalam urutan kesulitan yang meningkat

  1. Tampilkan lokasi untuk setiap perpindahan dalam format (kolom, baris) di daftar riwayat perpindahan
  2. Tebalkan item yang saat ini dipilih dalam daftar pemindahan
  3. Tulis ulang Papan untuk menggunakan dua loop untuk membuat kotak alih-alih melakukan hardcoding
  4. Tambahkan tombol sakelar yang memungkinkan Anda mengurutkan gerakan dalam urutan naik atau turun
  5. Saat seseorang menang, sorot tiga kotak yang menyebabkan kemenangan
  6. Ketika tidak ada yang menang, tampilkan pesan tentang hasil seri

Sepanjang tutorial ini, kita menyentuh konsep React termasuk elemen, komponen, properti, dan status. Untuk penjelasan yang lebih mendetail tentang masing-masing topik ini, lihat dokumentasi lainnya. Untuk mempelajari lebih lanjut tentang mendefinisikan komponen, lihat referensi class Board extends React.Component { renderSquare(i) { return <Square value={i} />; } }6 API

Apakah Bereaksi untuk HTML atau js?

Aplikasi React biasanya dibuat dengan satu elemen HTML .

Apakah Bereaksi dianggap sebagai JavaScript?

React adalah pustaka JavaScript yang deklaratif, efisien, dan fleksibel untuk membuat antarmuka pengguna. Ini memungkinkan Anda membuat UI kompleks dari potongan kode kecil dan terisolasi yang disebut "komponen".

Apakah Bereaksi dan HTML sama?

Penanganan event di HTML dan React berbeda satu sama lain dalam hal sintaksis dan beberapa aturan . Alasan di balik ini adalah bahwa React bekerja pada konsep DOM virtual, di sisi lain, HTML memiliki akses ke Real DOM sepanjang waktu.

Apakah react js lebih baik daripada HTML?

React js adalah alat yang luar biasa untuk setiap pengembang yang mahir dalam HTML dan ingin merancang situs web dinamis yang lebih cepat . HTML adalah bahasa web, tetapi mendesain situs web dengan HTML saja bisa menjadi tugas yang berulang dan tidak praktis.

Postingan terbaru

LIHAT SEMUA