Bạn đang xem : hướng dẫn phản ứng js cho người mới bắt đầu

Hướng dẫn này không thừa nhận bất kỳ kiến ​​thức React hiện có nào.

Trước khi Chúng tôi Bắt đầu Hướng dẫn

Chúng tôi sẽ xây dựng một trò chơi nhỏ trong suốt hướng dẫn này. Bạn có thể muốn bỏ qua nó vì bạn không xây dựng trò chơi – nhưng hãy cho nó cơ hội. Các kỹ thuật bạn sẽ học trong hướng dẫn này là cơ bản để xây dựng bất kỳ ứng dụng React nào và việc thành thạo nó sẽ mang lại bạn hiểu sâu sắc về React.

Mẹo

Hướng dẫn này được thiết kế cho những người thích học bằng cách làm . Nếu bạn muốn tìm hiểu các khái niệm từ đầu, hãy xem hướng dẫn từng bước của chúng tôi. Bạn có thể thấy hướng dẫn này và hướng dẫn bổ sung cho nhau.

Hướng dẫn được chia thành nhiều phần:

  • Thiết lập cho Hướng dẫn sẽ cung cấp cho bạn điểm bắt đầu để làm theo hướng dẫn.
  • Tổng quan sẽ dạy bạn các nguyên tắc cơ bản về React: các thành phần, đạo cụ và trạng thái.
  • Hoàn thành trò chơi sẽ dạy bạn các kỹ thuật phổ biến nhất trong quá trình phát triển React.
  • Thêm Du hành thời gian sẽ cung cấp cho bạn cái nhìn sâu sắc hơn về các điểm mạnh độc đáo của React.

Bạn không cần phải hoàn thành tất cả các phần cùng một lúc để nhận được giá trị từ hướng dẫn này. Cố gắng đi xa nhất có thể – ngay cả khi đó là một hoặc hai phần.

Chúng tôi đang xây dựng cái gì?

Trong hướng dẫn này, chúng tôi sẽ trình bày cách tạo một trò chơi tic-tac-toe tương tác với React.

Bạn có thể xem những gì chúng tôi sẽ xây dựng tại đây: Kết quả cuối cùng . Nếu mã không có ý nghĩa đối với bạn hoặc nếu bạn không quen với cú pháp của mã, đừng lo lắng! Mục tiêu của hướng dẫn này là giúp bạn hiểu React và cú pháp của nó.

Chúng tôi khuyên bạn nên xem trò chơi tic-tac-toe trước khi tiếp tục với hướng dẫn. Một trong những tính năng mà bạn sẽ nhận thấy là có một danh sách được đánh số ở bên phải bảng của trò chơi. Danh sách này cung cấp cho bạn lịch sử của tất cả các bước di chuyển đã xảy ra trong trò chơi và nó được cập nhật khi trò chơi tiến triển.

Bạn có thể đóng trò chơi tic-tac-toe khi đã quen với trò chơi này. Chúng tôi sẽ bắt đầu từ một mẫu đơn giản hơn trong hướng dẫn này. Bước tiếp theo của chúng tôi là thiết lập cho bạn để bạn có thể bắt đầu xây dựng trò chơi.

Điều kiện tiên quyết

Chúng tôi sẽ giả định rằng bạn đã quen với HTML và JavaScript, nhưng bạn sẽ có thể theo dõi ngay cả khi bạn đến từ một ngôn ngữ lập trình khác. Chúng tôi cũng sẽ cho rằng bạn đã quen thuộc với các khái niệm lập trình như hàm, đối tượng, mảng và ở mức độ thấp hơn là các lớp.

Nếu bạn cần xem lại JavaScript, chúng tôi khuyên bạn nên đọc hướng dẫn này . Lưu ý rằng chúng tôi cũng đang sử dụng một số tính năng từ ES6 – một phiên bản JavaScript gần đây. Trong hướng dẫn này, chúng tôi đang sử dụng các hàm mũi tên , các lớp , let const . Bạn có thể sử dụng Babel REPL để kiểm tra mã ES6 được biên dịch thành gì.

Thiết lập cho Hướng dẫn

Có hai cách để hoàn thành hướng dẫn này: bạn có thể viết mã trong trình duyệt của mình hoặc bạn có thể thiết lập môi trường phát triển cục bộ trên máy tính của mình.

Thiết lập Tùy chọn 1: Viết mã trong trình duyệt

Đây là cách nhanh nhất để bắt đầu!

Trước tiên, hãy mở Mã người mới bắt đầu này trong tab mới. Tab mới sẽ hiển thị bảng trò chơi tic-tac-toe trống và mã React. Chúng tôi sẽ chỉnh sửa mã React trong hướng dẫn này.

Giờ đây, bạn có thể bỏ qua tùy chọn thiết lập thứ hai và chuyển đến phần Tổng quan để biết tổng quan về React.

Thiết lập Tùy chọn 2: Môi trường phát triển cục bộ

Đây hoàn toàn là tùy chọn và không bắt buộc đối với hướng dẫn này!

Tùy chọn: Hướng dẫn làm theo cục bộ bằng trình soạn thảo văn bản ưa thích của bạn

Thiết lập này yêu cầu nhiều công việc hơn nhưng cho phép bạn hoàn thành hướng dẫn bằng trình chỉnh sửa bạn chọn. Dưới đây là các bước để làm theo:

  1. Đảm bảo rằng bạn đã cài đặt phiên bản gần đây của Node.js .
  2. Thực hiện theo hướng dẫn cài đặt Tạo ứng dụng React để tạo một dự án mới.
  npx create-react-app my-app  
  1. Xóa tất cả các tệp trong thư mục src / của dự án mới

Lưu ý:

Không xóa toàn bộ thư mục src , chỉ xóa các tệp nguồn gốc bên trong nó. Chúng tôi sẽ thay thế nguồn mặc định tệp với các ví dụ cho dự án này trong bước tiếp theo.

  

cd

my-app

cd

src

rm

-f * del *

cd

..

  1. Thêm tệp có tên index.css trong thư mục src / với mã CSS này .
  2. Thêm tệp có tên index.js trong thư mục src / với mã JS này .
  3. Thêm ba dòng này vào đầu index.js trong src / thư mục:
  

nhập

Phản ứng

từ < / p>

'phản ứng'

;

nhập

ReactDOM

từ

'react-dom / client'

< p class = "dấu chấm câu mã thông báo">;

nhập

'./ index.css'

;

Bây giờ nếu bạn chạy npm start trong thư mục dự án và mở http : // localhost: 3000 trong trình duyệt, bạn sẽ thấy trường tic-tac-toe trống.

Chúng tôi khuyên bạn nên làm theo các hướng dẫn này để định cấu hình đánh dấu cú pháp cho trình chỉnh sửa của bạn.

Nếu bạn gặp khó khăn, hãy xem tài nguyên hỗ trợ cộng đồng . Đặc biệt, Trò chuyện Reactiflux là một cách tuyệt vời để nhận trợ giúp nhanh chóng. Nếu bạn không nhận được câu trả lời hoặc nếu bạn vẫn gặp khó khăn, vui lòng gửi vấn đề và chúng tôi sẽ giúp bạn.

Tổng quan

Bây giờ bạn đã thiết lập xong, hãy cùng tìm hiểu tổng quan về React!

React là gì?

React là một thư viện JavaScript khai báo, hiệu quả và linh hoạt để xây dựng giao diện người dùng. Nó cho phép bạn tạo giao diện người dùng phức tạp từ các đoạn mã nhỏ và tách biệt được gọi là "thành phần".

React có một số loại thành phần khác nhau, nhưng chúng ta sẽ bắt đầu với các lớp con React.Component :

  

class

Danh sách mua sắm

mở rộng

React

.

Thành phần

< p class = "dấu chấm câu mã thông báo"> {

kết xuất

(

)

{

trả về

(

& lt;

div

className

=

"

danh sách mua sắm < p class = "dấu chấm câu"> "

& gt;

& lt;

h1

& gt;

Danh sách mua sắm cho

{

cái này

.

đạo cụ

.

tên

}

& lt; /

h1

& gt ;

& lt;

ul

& gt; < / p>

& lt;

li

& gt;

Instagram

& lt; /

li

& gt;

& lt;

li

& gt;

WhatsApp

& lt; /

li

& gt;

& lt;

li

& gt;

Oculus

& lt; /

li

& gt;

& lt; /

ul

& gt;

& lt; /

div

& gt;

)

;

}

}

Chúng ta sẽ sớm chuyển đến các thẻ giống XML vui nhộn. Chúng tôi sử dụng các thành phần để cho React biết những gì chúng tôi muốn thấy trên màn hình. Khi dữ liệu của chúng tôi thay đổi, React sẽ cập nhật và hiển thị lại các thành phần của chúng tôi một cách hiệu quả.

Ở đây, ShoppingList là một lớp thành phần React hoặc Loại thành phần React . Một thành phần nhận các tham số, được gọi là (viết tắt của “thuộc tính”) và trả về một hệ thống phân cấp các chế độ xem để hiển thị thông qua phương thức kết xuất .

Phương thức render trả về mô tả những gì bạn muốn xem trên màn hình. React lấy mô tả và hiển thị kết quả. Cụ thể, render trả về phần tử React , là một mô tả đơn giản về những gì cần kết xuất. Hầu hết các nhà phát triển React sử dụng một cú pháp đặc biệt có tên là “JSX” giúp các cấu trúc này dễ viết hơn. Cú pháp & lt; div / & gt; được chuyển đổi thành React.createElement ('div') Ví dụ trên tương đương với:

 

return

React

.

createElement

(

'div'

{

className

:

'danh sách mua sắm'

}

,

, < / p>

} p> React

.

createElement

(

'h1'

,

)

, > React

.

createElement

(

'ul'

,

)

)

;

Xem phiên bản mở rộng đầy đủ.

Nếu bạn tò mò, createElement () được mô tả chi tiết hơn trong tham chiếu API , nhưng chúng tôi sẽ không đang sử dụng nó trong hướng dẫn này. Thay vào đó, chúng tôi sẽ tiếp tục sử dụng JSX.

JSX đi kèm với toàn bộ sức mạnh của JavaScript. Bạn có thể đặt bất kỳ biểu thức JavaScript nào trong dấu ngoặc nhọn bên trong JSX. Mỗi phần tử React là một đối tượng JavaScript mà bạn có thể lưu trữ trong một biến hoặc chuyển xung quanh trong chương trình của mình.

Thành phần ShoppingList ở trên chỉ hiển thị các thành phần DOM tích hợp sẵn như & lt; div / & gt; & lt; li / & gt; . Nhưng bạn cũng có thể soạn và hiển thị các thành phần React tùy chỉnh. Ví dụ: bây giờ chúng ta có thể tham khảo toàn bộ danh sách mua sắm bằng cách viết & lt; ShoppingList / & gt; . Mỗi thành phần React được đóng gói và có thể hoạt động độc lập; điều này cho phép bạn tạo giao diện người dùng phức tạp từ các thành phần đơn giản.

Kiểm tra Mã khởi động

Nếu bạn đang thực hiện hướng dẫn trong trình duyệt của mình, hãy mở mã này trong tab mới: Mã người mới bắt đầu . Nếu bạn đang thực hiện hướng dẫn cục bộ, thay vào đó, hãy mở src / index.js trong thư mục dự án của bạn (bạn đã đã chạm vào tệp này trong quá trình thiết lập ).

Mã dành cho người mới bắt đầu này là nền tảng cho những gì chúng tôi đang xây dựng. Chúng tôi đã cung cấp kiểu CSS để bạn chỉ cần tập trung vào việc học React và lập trình trò chơi tic-tac-toe.

Bằng cách kiểm tra mã, bạn sẽ nhận thấy rằng chúng tôi có ba thành phần React:

  • Hình vuông
  • Bảng
  • Trò chơi

Thành phần Hình vuông hiển thị một nút & lt; & gt; và Bảng hiển thị 9 hình vuông. Thành phần Trò chơi hiển thị một bảng với các giá trị giữ chỗ mà chúng tôi sẽ sửa đổi sau. Hiện tại không có thành phần tương tác nào.

Truyền dữ liệu qua Props

Để chúng ta chân ướt chân ráo, hãy thử chuyển một số dữ liệu từ thành phần Board sang thành phần Square của chúng tôi.

Chúng tôi thực sự khuyên bạn nên nhập mã bằng tay khi bạn đang làm qua hướng dẫn và không sử dụng sao chép / dán. Điều này sẽ giúp bạn phát triển trí nhớ cơ bắp và hiểu biết nhiều hơn.

Trong phương thức renderSquare của Board, hãy thay đổi mã để chuyển một phần mềm có tên là value tới Quảng trường:

  

class

Bảng

mở rộng

React

.

Thành phần

< p class = "dấu chấm câu"> {

renderSquare

(

i

)

{

return

& lt;

Hình vuông

giá trị

=

{

i

}

/ & gt;

;

}

}

Thay đổi phương thức render của Square để hiển thị giá trị đó bằng thay thế {/ * VIỆC CẦN LÀM * /} bằng {this.props.value} : < / p>

  

class

Hình vuông

mở rộng

React

.

Thành phần

< p class = "dấu chấm câu"> {

kết xuất

(

)

{

trả về

(

& lt;

nút

className

=

"

vuông

"

& gt;

{

cái này

.

đạo cụ

.

value

}

& lt; /

nút

& gt;

)

;

}

}

Trước:

Sau: Bạn sẽ thấy một số trong mỗi ô vuông trong kết quả hiển thị.

Xem toàn bộ mã tại thời điểm này

Xin chúc mừng! Bạn vừa “chuyển chỗ dựa” từ thành phần Hội đồng quản trị mẹ sang thành phần Hình vuông con. Chuyển các đạo cụ là cách thông tin lưu chuyển trong ứng dụng React, từ cha mẹ đến trẻ em.

Tạo thành phần tương tác

Hãy điền vào thành phần Hình vuông với dấu "X" khi chúng ta nhấp vào nó.
Trước tiên, hãy thay đổi thẻ nút được trả về từ hàm render () của Square component thành hàm này:

  

class

Hình vuông

mở rộng

React

.

Thành phần

< p class = "dấu chấm câu"> {

kết xuất

(

)

{

trả về

(

& lt;

nút

className

=

"

vuông

"

onClick

=

{

hàm

(

)

{

console

.

nhật ký

(

'nhấp chuột' < / p>

)

;

}

}

& gt;

{

cái này

.

đạo cụ

.

value

}

Nút

& lt; /

& gt;

)

;

}

}

Nếu bạn nhấp vào Hình vuông ngay bây giờ, bạn sẽ thấy "nhấp chuột" trong bảng điều khiển dành cho nhà phát triển của trình duyệt.

Lưu ý

Để tiết kiệm việc nhập và tránh hành vi khó hiểu của này , chúng tôi sẽ sử dụng cú pháp hàm mũi tên cho các trình xử lý sự kiện ở đây và các phần khác bên dưới:

  

class

Hình vuông

mở rộng

React

.

Thành phần

< p class = "dấu chấm câu"> {

kết xuất

(

)

{

trả về

(

& lt;

nút

className

=

"

vuông

"

onClick

=

{

(

)

= & gt;

console

.

nhật ký

(

'nhấp chuột'

)

}

& gt;

{

cái này

.

đạo cụ

.

value

}

Nút

& lt; /

& gt;

)

;

}

}

Lưu ý cách thực hiện với onClick = {() = & gt; console.log ('click')} , chúng tôi đang chuyển một hàm làm phần mềm hỗ trợ onClick . React sẽ chỉ gọi hàm này sau một cú nhấp chuột. Quên () = & gt; và viết onClick = {console.log ('click')} là một lỗi phổ biến và sẽ kích hoạt mỗi khi thành phần hiển thị.

Bước tiếp theo, chúng tôi muốn thành phần Hình vuông “nhớ” rằng nó đã được nhấp và điền vào nó bằng dấu “X”. Để “ghi nhớ” mọi thứ, các thành phần sử dụng trạng thái .

Các thành phần React có thể có trạng thái bằng cách đặt this.state trong các hàm tạo của chúng. this.state phải được coi là riêng tư đối với một thành phần React mà nó được định nghĩa trong đó. Hãy lưu trữ giá trị hiện tại của Square trong this.state và thay đổi nó khi Square được nhấp vào.

Đầu tiên, chúng tôi sẽ thêm một hàm tạo vào lớp để khởi tạo trạng thái:

  

class

Hình vuông

mở rộng

React

.

Thành phần

< p class = "dấu chấm câu"> {

hàm tạo

(

đạo cụ

)

{

super

(

đạo cụ

)

;

cái này

.

state

=

{

giá trị

:

null

,

}

;

}

kết xuất

(

)

{

trả về

(

& lt;

nút

className

=

"

vuông

"

onClick

=

{

(

)

= & gt;

console

.

log

(

'nhấp chuột'

)

}

& gt;

{

cái này

.

đạo cụ

.

giá trị

}

Nút

& lt; /

& gt;

)

;

}

}

Lưu ý

Trong các lớp JavaScript , bạn cần luôn gọi super khi xác định phương thức khởi tạo của một lớp con. Tất cả các lớp thành phần React có constructor phải bắt đầu bằng lệnh gọi super (props) .

Bây giờ, chúng tôi sẽ thay đổi phương thức render của Square để hiển thị giá trị của trạng thái hiện tại khi được nhấp vào:

  • Thay thế this.props.value bằng this.state.value bên trong < code class = "gatsby-code-text"> & lt; nút & gt; thẻ.
  • Thay thế trình xử lý sự kiện onClick = {...} bằng onClick = {() = & gt ; this.setState ({value: 'X'})} .
  • Đặt các đạo cụ className onClick trên các dòng riêng biệt để dễ đọc hơn.

Sau những thay đổi này, nút & lt; & gt;Thẻ được trả về bởi phương thức render của Square trông giống như sau:

  

class

Hình vuông

mở rộng

React

.

Thành phần

< p class = "dấu chấm câu"> {

hàm tạo

(

đạo cụ

)

{

super

(

đạo cụ

)

;

this

.

state

=

{

value

:

null

,

}

;

}

kết xuất

(

)

{

trả về

(

& lt;

nút

className

=

"

vuông

"

onClick

=

{

(

)

= & gt;

this

.

setState

(

{

giá trị

< p class = "token operator">:

'X'

}

)

}

& gt; < / p>

{

this

.

bang

.

giá trị

}

& lt; /

nút

& gt;

)

;

}

}

Bằng cách gọi this.setState từ một onClick trình xử lý trong phương thức render của Square, chúng tôi yêu cầu React kết xuất lại Square đó bất cứ khi nào < code class = "gatsby-code-text"> & lt; nút & gt; được nhấp. Sau khi cập nhật, this.state.value của Square sẽ là 'X' , vì vậy chúng ta sẽ thấy X trên bảng trò chơi. Nếu bạn nhấp vào bất kỳ Hình vuông nào, X sẽ hiển thị.

Khi bạn gọi setState trong một thành phần, React cũng tự động cập nhật các thành phần con bên trong nó.

Xem toàn bộ mã tại thời điểm này

Tiện ích mở rộng React Devtools cho Chrome Firefox cho phép bạn kiểm tra cây thành phần React bằng các công cụ dành cho nhà phát triển của trình duyệt.



React DevTools cho phép bạn kiểm tra các đạo cụ và trạng thái của các thành phần React của bạn.

Sau khi cài đặt React DevTools, bạn có thể nhấp chuột phải vào bất kỳ phần tử nào trên trang, nhấp vào “Kiểm tra” để mở các công cụ dành cho nhà phát triển và các tab React (“⚛️ Thành phần” và “⚛️ Hồ sơ”) sẽ xuất hiện cuối cùng các tab ở bên phải. Sử dụng “⚛️ Thành phần” để kiểm tra cây thành phần.

Tuy nhiên, xin lưu ý rằng có một số bước bổ sung để làm cho nó hoạt động với CodePen:

  1. Đăng nhập hoặc đăng ký và xác nhận email của bạn (bắt buộc để ngăn chặn thư rác).
  2. Nhấp vào nút "Ngã ba".
  3. Nhấp vào “Thay đổi chế độ xem”, sau đó chọn “Chế độ gỡ lỗi”.
  4. Trong tab mới mở ra, giờ đây các devtools sẽ có tab React.

Hoàn thành trò chơi

Giờ đây, chúng tôi đã có các khối xây dựng cơ bản cho trò chơi tic-tac-toe của mình. Để có một trò chơi hoàn chỉnh, bây giờ chúng ta cần đặt xen kẽ các chữ “X” và “O” trên bàn cờ và chúng ta cần một cách để xác định người chiến thắng.

Nâng trạng thái lên

Hiện tại, mỗi thành phần Square duy trì trạng thái của trò chơi. Để tìm người chiến thắng, chúng tôi sẽ duy trì giá trị của từng ô trong số 9 ô vuông ở một vị trí.

Chúng tôi có thể nghĩ rằng Hội đồng quản trị chỉ nên hỏi từng Quảng trường về trạng thái của Quảng trường. Mặc dù cách tiếp cận này có thể thực hiện được trong React, nhưng chúng tôi không khuyến khích nó vì mã trở nên khó hiểu, dễ bị lỗi và khó tái cấu trúc. Thay vào đó, cách tốt nhất là lưu trữ trạng thái của trò chơi trong thành phần Bảng chính thay vì trong mỗi Hình vuông. Thành phần Hội đồng quản trị có thể cho mỗi Quảng trường biết những gì sẽ hiển thị bằng cách chuyển một chỗ dựa, giống như chúng tôi đã làm khi chuyển một số cho mỗi Hình vuông .

Để thu thập dữ liệu từ nhiều thành phần con hoặc để hai thành phần con giao tiếp với nhau, bạn cần khai báo trạng thái được chia sẻ trong thành phần mẹ của chúng. Thành phần cha có thể truyền lại trạng thái cho con bằng cách sử dụng các đạo cụ; điều này giúp các thành phần con đồng bộ với nhau và với thành phần mẹ.

Việc nâng trạng thái thành một thành phần chính là điều phổ biến khi các thành phần React được cấu trúc lại - hãy tận dụng cơ hội này để dùng thử.

Thêm một hàm tạo vào Bảng và đặt trạng thái ban đầu của Bảng để chứa một mảng gồm 9 ô trống tương ứng với 9 ô vuông:

  

class

Bảng

mở rộng

React

.

Thành phần

< p class = "dấu chấm câu mã thông báo"> {

hàm tạo

(

đạo cụ

)

{

super

(

đạo cụ

)

;

cái này

.

state

=

{

hình vuông

:

Mảng

(

9

)

. < / p>

điền

(

rỗng

)

,

}

;

}

renderSquare

(

i

)

{

trả về

& lt;

Hình vuông

value

=

{

i

}

/ & gt;

;

}

Khi chúng tôi điền vào bảng sau, this.state. mảng vuông sẽ trông giống như sau:

  

[

'O'

,

null

,

'X'

,

'X'

,

'X'

,

'O'

,

'O'

,

null

,

rỗng

,

]

Phương thức renderSquare của Board hiện có dạng như sau:

  

renderSquare

(

i

)

{

trả về

& lt;

Hình vuông

value

=

{

i

}

/ & gt;

;

}

Ban đầu, chúng tôi đã chuyển giá trị chống xuống từ Bảng để hiển thị các số từ 0 đến 8 ở mọi Hình vuông. Trong một bước khác trước đó, chúng tôi đã thay thế các số bằng dấu “X” được xác định bởi chính trạng thái của Square . Đây là lý do tại sao Square hiện bỏ qua prop value mà Hội đồng quản trị đã chuyển cho nó.

Bây giờ chúng tôi sẽ sử dụng lại cơ chế chuyển động chống đỡ. Chúng tôi sẽ sửa đổi Hội đồng quản trị để hướng dẫn từng Hình vuông riêng lẻ về giá trị hiện tại của nó ( 'X' , 'O' hoặc null ). Chúng tôi đã xác định mảng square trong hàm tạo của Board và chúng tôi sẽ sửa đổi renderSquare phương pháp để đọc từ nó:

  

renderSquare

(

i

)

{

return

& lt;

Hình vuông

giá trị

=

{

cái này

.

bang

.

vuông

[

i < p class = "dấu chấm câu">]

}

/ & gt;

;

}

Xem toàn bộ mã tại thời điểm này

Giờ đây, mỗi Hình vuông sẽ nhận được một prop giá trị sẽ là 'X' , 'O' hoặc null cho các ô trống.

Tiếp theo, chúng ta cần thay đổi điều gì sẽ xảy ra khi một Hình vuông được nhấp vào. Thành phần Board hiện duy trì những ô vuông nào được lấp đầy. Chúng tôi cần tạo một cách để Square cập nhật trạng thái của Board. Vì trạng thái được coi là riêng tư đối với thành phần xác định nó, chúng tôi không thể cập nhật trạng thái của Hội đồng quản trị trực tiếp từ Square.

Thay vào đó, chúng tôi sẽ chuyển một hàm từ Bảng sang Hình vuông và chúng tôi sẽ để Square gọi hàm đó khi một hình vuông được nhấp vào. Chúng tôi sẽ thay đổi phương thức renderSquare trong Board thành:

  

renderSquare

(

i

)

{

trả về

(

& lt;

Hình vuông

< / p>

value

=

{

cái này

.

bang

. ô vuông

[

i

]

}

onClick

=

{

(

)

= & gt;

cái này

.

handleClick

(

i

)

}

/ & gt;

)

;

}

Lưu ý

Chúng tôi chia phần tử trả về thành nhiều dòng để dễ đọc và thêm dấu ngoặc đơn để JavaScript không chèn dấu chấm phẩy sau return và ngắt mã của chúng tôi. < / p>

Bây giờ, chúng tôi đang chuyển hai đạo cụ từ Board sang Square: value onClick . Prop onClick là một hàm mà Square có thể gọi khi được nhấp vào. Chúng tôi sẽ thực hiện những thay đổi sau đối với Square:

  • Thay thế this.state.value bằng this.props.value trong < code class = "gatsby-code-text"> phương thức kết xuất
  • Thay thế this.setState () bằng this.props.onClick () trong Phương thức kết xuất của Square
  • Xóa constructor khỏi Square vì Square không còn theo dõi trạng thái của trò chơi

Sau những thay đổi này, thành phần Square trông giống như sau:

  

class

Square

mở rộng

React

.

Thành phần

{

kết xuất

(

)

{

trả về

(

& lt;

nút

className

=

"

hình vuông

"

onClick

=

{

(

)

= & gt;

cái này

.

đạo cụ

.

onClick

(

)

}

& gt;

{

cái này

.

đạo cụ

.

value

}

& lt; /

nút

& gt;

)

;

}

}

Khi một Hình vuông được nhấp, hàm onClick được cung cấp bởi Hội đồng quản trị được gọi. Dưới đây là đánh giá về cách đạt được điều này:

  1. onClick dựa trên thành phần DOM & lt; button & gt; tích hợp sẵn cho biết React để thiết lập trình xử lý sự kiện nhấp chuột.
  2. Khi nút được nhấp, React sẽ gọi trình xử lý sự kiện onClick được xác định trong kết xuất của Square () .
  3. Trình xử lý sự kiện này gọi this.props.onClick () . Hội đồng quản trị chỉ định phương án hỗ trợ onClick của Square.
  4. Vì Hội đồng đã vượt qua onClick = {() = & gt; this.handleClick (i)} đến Square, Square gọi handleClick (i) của Board khi được nhấp.
  5. Chúng tôi chưa xác định phương thức handleClick () , vì vậy mã của chúng tôi bị lỗi. Nếu bạn nhấp vào một hình vuông ngay bây giờ, bạn sẽ thấy màn hình lỗi màu đỏ có nội dung như “this.handleClick không phải là một chức năng”.

Lưu ý

& lt; button & gt; phần tử của DOM onClickThuộc tính có một ý nghĩa đặc biệt đối với React vì nó là một thành phần được tích hợp sẵn. Đối với các thành phần tùy chỉnh như Square, việc đặt tên là tùy thuộc vào bạn. Chúng tôi có thể đặt bất kỳ tên nào cho phương thức onClick prop của Square hoặc handleClick của Square và mã sẽ hoạt động như nhau. Trong React, thông thường sử dụng tên trên [Sự kiện] cho các đạo cụ đại diện cho các sự kiện và xử lý [Sự kiện] cho các phương thức xử lý các sự kiện.

Khi cố gắng nhấp vào Hình vuông, chúng tôi sẽ gặp lỗi vì chúng tôi chưa xác định handleClick . Bây giờ chúng tôi sẽ thêm handleClick vào lớp Board:

  

class

Bảng

mở rộng

React

.

Thành phần

< p class = "dấu chấm câu mã thông báo"> {

hàm tạo

(

đạo cụ

)

{

super

(

đạo cụ

)

;

this

.

state

=

{

ô vuông

:

Mảng

(

9

)

.

điền

(

rỗng

)

,

}

;

}

handleClick

(

tôi

)

{

const

vuông

=

cái này

.

bang

.

vuông

.

lát < / p>

(

)

;

< p class = "gatsby-highlight-code-line"> vuông

[

i

]

=

'X'

;

cái này

.

setState

(

{

ô vuông

:

hình vuông

}

)

;

< / p>

}

renderSquare

(

i

)

{

trả về

(

& lt;

Hình vuông

< / p>

value

=

{

cái này

.

bang

. ô vuông

[

i

]

}

onClick

=

{

(

)

= & gt; < / p>

cái này

.

handleClick

(

i

)

}

/ & gt;

)

;

}

kết xuất

(

)

{

const

status

=

'Trình phát tiếp theo: X'

;

trả về

(

& lt;

div

& gt; < / p>

& lt;

div < / p>

className

=

"

trạng thái

"

& gt;

< p class = "dấu chấm câu"> {

trạng thái

}

& lt; /

div

& gt;

& lt;

div < / p>

className

=

"

board-row

"

& gt;

{

cái này

.

renderSquare

(

0

< p class = "dấu chấm câu mã thông báo">)

}

{

cái này

.

renderSquare

(

1

< p class = "dấu chấm câu mã thông báo">)

}

{

cái này

.

renderSquare

(

2

< p class = "dấu chấm câu mã thông báo">)

}

& lt; /

div

& gt;

& lt;

div < / p>

className

=

"

board-row

"

& gt;

{

cái này

.

renderSquare

(

3

< p class = "dấu chấm câu mã thông báo">)

}

{

cái này

.

renderSquare

(

4

< p class = "dấu chấm câu mã thông báo">)

}

{

cái này

.

renderSquare

(

5

< p class = "dấu chấm câu mã thông báo">)

}

& lt; /

div

& gt;

& lt;

div < / p>

className

=

"

board-row

"

& gt;

{

cái này

.

renderSquare

(

6

< p class = "dấu chấm câu">)

}

{

cái này

.

renderSquare

(

7

< p class = "dấu chấm câu mã thông báo">)

}

{

cái này

.

renderSquare

(

8

< p class = "dấu chấm câu mã thông báo">)

}

& lt; /

div

& gt;

& lt; /

div

& gt;

)

;

}

}

Xem toàn bộ mã tại thời điểm này

Sau những thay đổi này, chúng tôi lại có thể nhấp vào Hình vuông để điền chúng, giống như chúng tôi đã làm trước đây. Tuy nhiên, bây giờ trạng thái được lưu trữ trong thành phần Board thay vì các thành phần Square riêng lẻ. Khi trạng thái của Board thay đổi, các thành phần Square sẽ tự động hiển thị lại. Giữ trạng thái của tất cả các ô vuông trong thành phần Bảng sẽ cho phép nó xác định người chiến thắng trong tương lai.

Vì các thành phần Square không còn duy trì trạng thái, các thành phần Square nhận các giá trị từ thành phần Board và thông báo cho thành phần Board khi chúng được nhấp vào. Theo thuật ngữ React, các thành phần Square hiện là thành phần được kiểm soát . Hội đồng quản trị có toàn quyền kiểm soát chúng.

Lưu ý rằng trong handleClick , chúng tôi gọi . slice () để tạo một bản sao của mảng square để sửa đổi thay vì sửa đổi mảng hiện có. Chúng tôi sẽ giải thích lý do tại sao chúng tôi tạo bản sao của mảng square trong phần tiếp theo.

Tại sao tính bất biến lại quan trọng

Trong ví dụ về mã trước đó, chúng tôi khuyên bạn nên tạo bản sao của mảng square bằng cách sử dụng phương thức slice () thay vì sửa đổi mảng hiện có. Bây giờ chúng ta sẽ thảo luận về tính bất biến và lý do tại sao tính bất biến lại quan trọng để tìm hiểu.

Nhìn chung, có hai cách tiếp cận để thay đổi dữ liệu. Cách tiếp cận đầu tiên là thay đổi dữ liệu bằng cách thay đổi trực tiếp các giá trị của dữ liệu. Cách thứ hai là thay thế dữ liệu bằng một bản sao mới có những thay đổi mong muốn.

Thay đổi dữ liệu có đột biến

  

var

player

= < / p>

{

điểm

:

1

,

tên

:

'Jeff'

}

; người chơi

.

điểm

=

2

;

Thay đổi dữ liệu mà không có đột biến

  

var

player

= < / p>

{

điểm

:

1

,

tên

:

'Jeff'

}

;

var

newPlayer

=

Đối tượng

.

gán

(

{

}

,

người chơi

,

{

điểm

:

2

}

)

;

Kết quả cuối cùng là giống nhau nhưng bằng cách không trực tiếp thay đổi (hoặc thay đổi dữ liệu cơ bản), chúng tôi đạt được một số lợi ích được mô tả bên dưới.

Các tính năng phức tạp trở nên đơn giản

Tính bất biến làm cho các tính năng phức tạp dễ triển khai hơn nhiều. Ở phần sau của hướng dẫn này, chúng tôi sẽ triển khai tính năng “du hành thời gian” cho phép chúng tôi xem lại lịch sử trò chơi tic-tac-toe và “quay lại” các bước di chuyển trước đó. Chức năng này không dành riêng cho trò chơi - khả năng hoàn tác và làm lại các hành động nhất định là yêu cầu phổ biến trong các ứng dụng. Việc tránh đột biến dữ liệu trực tiếp cho phép chúng tôi giữ nguyên vẹn các phiên bản trước của lịch sử trò chơi và sử dụng lại chúng sau này.

Phát hiện thay đổi

Rất khó phát hiện các thay đổi trong các đối tượng có thể thay đổi vì chúng được sửa đổi trực tiếp. Việc phát hiện này yêu cầu đối tượng có thể thay đổi được so sánh với các bản sao trước đó của chính nó và toàn bộ cây đối tượng phải được duyệt qua.

Việc phát hiện các thay đổi trong các đối tượng không thể thay đổi dễ dàng hơn đáng kể. Nếu đối tượng bất biến đang được tham chiếu khác với đối tượng trước đó, thì đối tượng đó đã thay đổi.

Xác định thời điểm hiển thị lại trong React

Lợi ích chính của tính bất biến là nó giúp bạn xây dựng các thành phần thuần túy trong React. Dữ liệu bất biến có thể dễ dàng xác định xem các thay đổi đã được thực hiện hay chưa, giúp xác định thời điểm một thành phần yêu cầu hiển thị lại.

Bạn có thể tìm hiểu thêm về shouldComponentUpdate () và cách bạn có thể tạo các thành phần thuần túy bằng cách đọc Tối ưu hóa hiệu suất .

Thành phần chức năng

Bây giờ, chúng tôi sẽ thay đổi Hình vuông thành một thành phần chức năng .

Trong React, các thành phần hàm là cách đơn giản hơn để viết các thành phần chỉ chứa phương thức kết xuất và không có trạng thái riêng. Thay vì xác định một lớp mở rộng React.Component , chúng ta có thể viết một hàm sử dụng props dưới dạng đầu vào và trả về những gì sẽ được hiển thị. Các thành phần hàm ít nhàm chán hơn khi viết so với các lớp và nhiều thành phần có thể được thể hiện theo cách này.

Thay thế lớp Square bằng hàm này:

  

function

Square

(

đạo cụ

)

{

trả về

(

& lt;

nút

className

=

"

vuông

"

onClick

=

{

đạo cụ

.

onClick

}

& gt;

{

đạo cụ

.

value

}

& lt; /

nút

& gt;

)

;

}

Chúng tôi đã thay đổi this.props thành props cả hai lần nó xuất hiện.

Xem toàn bộ mã tại thời điểm này

Lưu ý

Khi chúng tôi sửa đổi Hình vuông thành một thành phần hàm, chúng tôi cũng đã thay đổi onClick = {() = & gt; this.props.onClick ()} đến onClick = {props.onClick} ngắn hơn (lưu ý thiếu dấu ngoặc đơn ở cả hai bên). < / p>

Lượt đi

Giờ đây, chúng tôi cần sửa một khuyết điểm rõ ràng trong trò chơi tic-tac-toe: không thể đánh dấu chữ “O” trên bàn cờ.

Theo mặc định, chúng tôi sẽ đặt nước đi đầu tiên là “X”. Chúng tôi có thể đặt mặc định này bằng cách sửa đổi trạng thái ban đầu trong trình tạo Bảng của chúng tôi:

  

class

Bảng

mở rộng

React

.

Thành phần

{

hàm tạo

(

đạo cụ

)

{

super

(

đạo cụ

)

;

this

.

state

=

{

ô vuông

:

Mảng

(

9

)

.

điền

(

rỗng

)

,

xIsNext

:

true

,

}

;

}

Mỗi khi người chơi di chuyển, xIsNext (a boolean) sẽ được lật để xác định người chơi nào đi tiếp và trạng thái của trò chơi sẽ được lưu. Chúng tôi sẽ cập nhật hàm handleClick của Board để lật giá trị của xIsNext :

  

handleClick

(

i

)

{

const

square

=

this

.

trạng thái

.

hình vuông

.

lát

(

)

;

vuông

[

i

]

=

cái này

.

trạng thái

. xIsNext

?

'X'

:

'O'

;

này

.

setState

(

{

hình vuông

:

hình vuông

,

xIsNext

:

!

này

.

bang

. xIsNext

,

}

)

< p class = "dấu chấm câu mã thông báo">;

}

Với thay đổi này, “X” và “O” có thể thay phiên nhau. Hãy thử nó!

Hãy cũng thay đổi văn bản “trạng thái” trong render của Board để hiển thị người chơi nào có lượt tiếp theo:

  

kết xuất

(

)

{

const

status

=

'Trình phát tiếp theo:'

+

(

this < / p>

.

bang

.

xIsNext

?

'X'

:

'O'

)

;

trả về

(

Sau khi áp dụng những thay đổi này, bạn sẽ có thành phần Hội đồng quản trị này:

  

class

Bảng

mở rộng

React

.

Thành phần

< p class = "dấu chấm câu mã thông báo"> {

hàm tạo

(

đạo cụ

)

{

super

(

đạo cụ

)

;

this

.

state

=

{

ô vuông

:

Mảng

(

9

)

.

điền

(

rỗng

)

,

xIsNext

:

true

,

}

;

}

handleClick

(

i

)

{

const

vuông

=

this

.

bang

.

hình vuông

.

lát cắt

(

)

;

vuông

[

i

]

=

this

.

trạng thái

.

xIsNext

?

'X'

:

'O'

;

cái này

.

setState

(

{

hình vuông

:

hình vuông

,

xIsNext

:

!

< p class = "từ khóa mã thông báo"> cái này

.

bang

.

xIsNext

,

}

) < / p>

;

}

renderSquare

(

i

)

{

trả về

(

& lt;

Hình vuông

< / p>

value

=

{

cái này

.

bang

. ô vuông

[

i

]

}

onClick

=

{

(

)

= & gt; < / p>

cái này

.

handleClick

(

i

)

}

/ & gt;

)

;

}

kết xuất

(

)

{

const

status

=

'Trình phát tiếp theo:'

+

(

this < / p>

.

bang

.

xIsNext

?

'X'

:

'O'

)

;

return

(

& lt;

div

& gt; < / p>

& lt;

div < / p>

className

=

"

trạng thái

"

& gt;

< p class = "dấu chấm câu"> {

trạng thái

}

& lt; /

div

& gt;

& lt;

div < / p>

className

=

"

board-row

"

& gt;

{

cái này

.

rendersSquare

(

0

< p class = "dấu chấm câu mã thông báo">)

}

{

cái này

.

rendersSquare

(

1

< p class = "dấu chấm câu mã thông báo">)

}

{

cái này

.

rendersSquare

(

2

< p class = "dấu chấm câu mã thông báo">)

}

& lt; /

div

& gt;

& lt;

div < / p>

className

=

"

board-row

"

& gt;

{

cái này

.

rendersSquare

(

3

< p class = "dấu chấm câu mã thông báo">)

}

{

cái này

.

rendersSquare

(

4

< p p class = "dấu chấm câu mã thông báo">)

}

{

cái này

.

rendersSquare

(

5

< p class = "dấu chấm câu mã thông báo">)

}

& lt; /

div

& gt;

& lt;

div < / p>

className

=

"

board-row

"

& gt;

{

cái này

.

rendersSquare

(

6

< p class = "dấu chấm câu">)

}

{

cái này

.

renderSquare

(

7

< p class = "dấu chấm câu mã thông báo">)

}

{

cái này

.

renderSquare

(

8

< p class = "dấu chấm câu mã thông báo">)

}

& lt; /

div

& gt;

& lt; /

div

& gt;

)

;

}

}

Xem toàn bộ mã tại thời điểm này

Tuyên bố người chiến thắng

Bây giờ chúng tôi hiển thị lượt tiếp theo của người chơi nào, chúng tôi cũng sẽ hiển thị khi trò chơi đã thắng và không còn lượt nào để thực hiện nữa. Sao chép hàm trợ giúp này và dán vào cuối tệp:

  

function

mathWinner

(

ô vuông

)

{

const

lines

=

[

[

0

,

1

,

2

]

,

[

3

,

4

,

5

]

,

[

6

,

7

,

8

]

,

[

0

,

3

,

6

]

,

[

1

,

4

,

7

]

,

[

2

,

5

,

8

]

,

[

0

,

4

,

8

]

,

[

2

,

4

,

6

]

,

]

;

cho

(

let

i

=

0

;

i

& lt; dòng

.

length

;

i

++

)

{

const

[

a

,

b

,

c

]

=

dòng

[ i

]

;

if

(

hình vuông

[

a

]

& amp; & amp;

hình vuông

[

a

]

===

vuông

[

b

]

& amp; & amp;

hình vuông

[

a

]

===

vuông

[

c

]

)

{

trả về

vuông

[

a

]

;

}

}

return

null

;

}

Cho một mảng 9 ô vuông, hàm này sẽ kiểm tra người chiến thắng và trả về 'X' , 'O' hoặc null như thích hợp.

Chúng tôi sẽ gọi allowWinner (square) trong hàm render của Board để kiểm tra xem một người chơi đã chiến thắng. Nếu một người chơi đã thắng, chúng tôi có thể hiển thị văn bản như “Người chiến thắng: X” hoặc “Người chiến thắng: O”. Chúng tôi sẽ thay thế khai báo status trong hàm render của Board bằng mã này:

  

kết xuất

(

)

{

const

thắng

=

allowWinner

(

cái này

.

trạng thái

.

vuông

)

;

để

trạng thái

;

nếu

(

người chiến thắng

)

{

trạng thái

=

'Người chiến thắng:'

+

Người chiến thắng

;

}

khác

{

status

=

'Trình phát tiếp theo:'

+

(

cái này

.

bang

.

xIsNext

?

< p class = "chuỗi mã thông báo"> 'X'

:

'O'

)

;

}

trả về

(

Giờ đây, chúng tôi có thể thay đổi chức năng handleClick của Board để quay lại sớm bằng cách bỏ qua một lần nhấp nếu ai đó đã thắng trò chơi hoặc nếu một Hình vuông đã được lấp đầy:

  

handleClick

(

i

)

{

const

square

=

this

.

trạng thái

.

hình vuông

.

lát

(

)

;

if

(

allowWinner

(

hình vuông

)

||

hình vuông

[

i

]

)

{

return

;

}

vuông

[

i

]

=

cái này

.

bang

.

xIsNext

?

'X'

:

'O'

;

this

setState

> (

{

hình vuông

:

hình vuông

,

xIsNext

:

!

cái này

.

bang

.

xIsNext

, < / p>

}

)

;

}

Xem toàn bộ mã tại thời điểm này

Xin chúc mừng! Bây giờ bạn có một trò chơi tic-tac-toe đang hoạt động. Và bạn cũng vừa học những kiến ​​thức cơ bản về React. Vì vậy, bạn có thể là người chiến thắng thực sự ở đây.

Du hành thêm thời gian

Là bài tập cuối cùng, hãy giúp bạn có thể “quay ngược thời gian” về các bước di chuyển trước đó trong trò chơi

Lưu trữ lịch sử di chuyển

Nếu chúng tôi đã thay đổi mảng square , thì việc triển khai du hành thời gian sẽ rất khó khăn

Tuy nhiên, chúng tôi đã sử dụng để tạo một bản sao mới của mảng square sau mỗi lần di chuyển và đã xử lý nó như bất biến . Điều này sẽ cho phép chúng tôi lưu trữ mọi phiên bản trước đây của mảng square và điều hướng giữa các lượt đã xảy ra.

Chúng tôi sẽ lưu trữ các mảng square trước đây trong một mảng khác có tên là history . Mảng history đại diện cho tất cả các trạng thái của bảng, từ nước đi đầu tiên đến nước đi cuối cùng và có hình dạng như sau:

  history 

=

[< / p>

{

hình vuông

:

[

null

,

null

,

không có giá trị nào

,

null

,

null

,

không có giá trị nào

,

null

,

null

,

không có giá trị nào

,

]

}

,

{

hình vuông

:

[

null

,

null

,

không có giá trị nào

,

null

,

'X'

,

rỗng

,

null

,

null

,

không có giá trị nào

,

]

}

,

{

hình vuông

:

[

null

,

null

,

không có giá trị nào

,

null

,

'X'

,

null

,

null

,

null

,

'O'

,

]

}

,

]

Bây giờ chúng ta cần quyết định thành phần nào nên sở hữu history trạng thái.

Nâng trạng thái lên một lần nữa

Chúng tôi muốn thành phần Trò chơi cấp cao nhất hiển thị danh sách các nước đi trong quá khứ. Nó sẽ cần quyền truy cập vào history để làm điều đó, vì vậy chúng tôi sẽ đặt trạng thái history trong thành phần Trò chơi cấp cao nhất.

Đặt trạng thái history vào thành phần Trò chơi cho phép chúng tôi xóa trạng thái square khỏi thành phần Hội đồng quản trị con của nó. Cũng giống như chúng tôi “nâng trạng thái” từ thành phần Hình vuông thành thành phần Bảng, hiện chúng tôi đang nâng từ Bảng thành thành phần Trò chơi cấp cao nhất. Điều này cho phép thành phần Trò chơi toàn quyền kiểm soát dữ liệu của Bảng và cho phép Thành phần này hướng dẫn Bảng hiển thị các lượt trước từ lịch sử .

Đầu tiên, chúng tôi sẽ thiết lập trạng thái ban đầu cho thành phần Trò chơi trong hàm tạo của nó:

  

class

Trò chơi

mở rộng

React

.

Thành phần

< p class = "dấu chấm câu mã thông báo"> {

hàm tạo

(

đạo cụ

)

{

super

(

đạo cụ

)

;

cái này

.

state

=

{

lịch sử

:

[

{

ô vuông

:

Mảng

(

< p class = "số mã thông báo"> 9

)

.

điền

(

rỗng

)

,

}

]

,

xIsNext

:

true

,

}

;

}

kết xuất

(

)

{

trả về

(

& lt;

div

className

=

"

trò chơi

"

& gt;

& lt;

div < / p>

className

=

"

game-board

"

& gt;

& lt;

Bảng

/ & gt;

< / p>

& lt; /

div

& gt;

& lt;

div < / p>

className

=

"

game-info

"

& gt;

& lt;

div < / p>

& gt;

{

}

& lt; /

div

& gt;

& lt;

ol < / p>

& gt;

{

}

& lt; /

ol

& gt;

& lt; /

div

& gt;

& lt; /

div

& gt;

)

;

}

}

Tiếp theo, chúng ta sẽ để thành phần Bảng nhận ô vuông onClick props từ thành phần Trò chơi. Vì hiện tại chúng tôi có một trình xử lý nhấp chuột duy nhất trong Bảng cho nhiều Hình vuông, chúng tôi sẽ cần chuyển vị trí của từng Hình vuông vào trình xử lý onClick để cho biết Hình vuông nào là đã nhấp vào. Dưới đây là các bước bắt buộc để chuyển đổi thành phần Hội đồng quản trị:

  • Xóa constructor trong Board.
  • Thay thế this.state.squares [i] bằng this.props.squares [i] < / code> trong renderSquare của Board.
  • Thay thế this.handleClick (i) bằng this.props.onClick (i) trong renderSquare của Board.

Thành phần Hội đồng quản trị bây giờ trông giống như sau:

  

class

Bảng

mở rộng

React

.

Thành phần

< p class = "dấu chấm câu"> {

handleClick

(

i

)

{

const

square

=

this

.

trạng thái

.

hình vuông

.

lát

(

)

;

nếu

(

CalculWinner

(

ô vuông

)

||

ô vuông

[ i

]

)

{

trả về

;

}

hình vuông

[

i

]

=

this

.

bang

.

xIsNext

?

'X'

:

'O'

;

this

.

setState

(

{

hình vuông

:

hình vuông

,

xIsNext

:

!

this

.

bang

.

xIsNext

,

}

)

;

}

renderSquare

(

i

)

{

trả về

(

& lt;

Hình vuông

< / p>

value

=

{

cái này

. đạo cụ

.

hình vuông

[

i

]

}

onClick

=

{

(

)

= & gt;

this

< p class = "dấu chấm câu">.

đạo cụ

.

onClick

(

i

)

} < / p>

/ & gt;

)

;

}

kết xuất

(

)

{

const

winner

=

CalculWinner

(

cái này

.

bang

.

hình vuông

)

;

để

trạng thái

;

if

(

winner

)

{

status

=

'Người chiến thắng:'

+

Người chiến thắng

;

}

khác

{

status

=

'Trình phát tiếp theo:'

+

(

cái này

.

bang

.

xIsNext

?

'X'

:

< p class = "token string"> 'O'

)

;

}

trả về

(

& lt;

div

& gt; < / p>

& lt;

div < / p>

className

=

"

trạng thái

"

& gt;

< p class = "dấu chấm câu"> {

trạng thái

}

& lt; /

div

& gt;

& lt;

div < / p>

className

=

"

board-row

"

& gt;

{

cái này

.

renderSquare

(

0

< p class = "dấu chấm câu mã thông báo">)

}

{

this

.

renderSquare

(

1

)

}

{

cái này

.

renderSquare

(

2

< p class = "dấu chấm câu mã thông báo">)

}

& lt; /

div

& gt;

& lt;

div < / p>

className

=

"

board-row

"

& gt;

{

cái này

.

renderSquare

(

3

< p class = "dấu chấm câu mã thông báo">)

}

{

cái này

.

renderSquare

(

4

< p class = "dấu chấm câu mã thông báo">)

}

{

cái này

.

renderSquare

(

5

< p class = "dấu chấm câu mã thông báo">)

}

& lt; /

div

& gt;

& lt;

div < / p>

className

=

"

board-row

"

& gt;

{

cái này

.

renderSquare

(

6

< p class = "dấu chấm câu mã thông báo">)

}

{

cái này

.

renderSquare

(

7

< p class = "dấu chấm câu mã thông báo">)

}

{

cái này

.

renderSquare

(

8

< p class = "dấu chấm câu mã thông báo">)

}

& lt; /

div

& gt;

& lt; /

div

& gt;

)

;

}

}

Chúng tôi sẽ cập nhật chức năng kết xuất của thành phần Trò chơi sử dụng mục lịch sử gần đây nhất để xác định và hiển thị trạng thái của trò chơi:

  

kết xuất

(

)

{

const

lịch sử

=

this

.

bang

.

lịch sử

;

const

hiện tại

=

lịch sử

[

lịch sử

.

length

-

1

]

;

const

người chiến thắng

=

allowWinner

(

.

hình vuông

)

;

để

trạng thái

;

if

(

người chiến thắng

)

{

trạng thái

=

'Người chiến thắng:'

+ người chiến thắng

;

}

else

{

status

=

'Trình phát tiếp theo:'

+

(

cái này

.

bang

.

xIsNext < p class = "token operator">?

'X'

:

'O'

)

;

}

trả về

(

& lt;

div

className

=

"

trò chơi

"

& gt;

& lt;

div < / p>

className

=

"

game-board

"

& gt;

& lt;

Bảng

ô vuông

=

{

hiện tại

.

hình vuông

}

onClick

=

{

(

tôi

)

= & gt;

cái này

.

handleClick

(

i

)

}

/ & gt;

& lt; /

div

& gt;

& lt;

div < / p>

className

=

"

game-info

"

& gt;

& lt;

div

& gt;

{

trạng thái

}

& lt; /

div

& gt;

& lt;

ol

& gt;

{

}

& lt; /

ol

& gt;

& lt; /

div

& gt;

& lt; /

div

& gt;

)

;

}

Vì thành phần Trò chơi hiện đang hiển thị trạng thái của trò chơi, chúng tôi có thể xóa mã tương ứng khỏi kết xuất . Sau khi cấu trúc lại, hàm render của Board trông giống như sau:

  

kết xuất

(

)

{

return

(

& lt;

div

& gt;

& lt;

div

className

=

"

board-row

"

& gt;

< p class = "token pure-text">

{

this

.

renderSquare

(

0

)

}

{

cái này

.

renderSquare

(

1

< p class = "dấu chấm câu mã thông báo">)

}

{

cái này

.

renderSquare

(

2

< p class = "dấu chấm câu mã thông báo">)

}

& lt; /

div

& gt;

& lt;

div < / p>

className

=

"

board-row

"

& gt;

{

cái này

.

renderSquare

(

3

< p class = "dấu chấm câu mã thông báo">)

}

{

cái này

.

renderSquare

(

4

< p class = "dấu chấm câu mã thông báo">)

}

{

cái này

.

renderSquare

(

5

< p class = "dấu chấm câu mã thông báo">)

}

& lt; /

div

& gt;

& lt;

div < / p>

className

=

"

board-row

"

& gt;

{

cái này

.

renderSquare

(

6

< p class = "dấu chấm câu mã thông báo">)

}

{

cái này

.

renderSquare

(

7

< p class = "dấu chấm câu mã thông báo">)

}

{

cái này

.

renderSquare

(

8

< p class = "dấu chấm câu mã thông báo">)

}

& lt; /

div

& gt;

& lt; /

div

& gt;

)

;

}

Cuối cùng, chúng ta cần di chuyển phương thức handleClick từ thành phần Hội đồng quản trị đến thành phần Trò chơi. Chúng tôi cũng cần sửa đổi handleClick vì trạng thái của thành phần Trò chơi được cấu trúc khác nhau. Trong phương thức handleClick của Trò chơi, chúng tôi nối các mục lịch sử mới vào history .

  

handleClick

(

i

)

{

const

lịch sử

=

this

.

bang

.

lịch sử

;

const

hiện tại

=

lịch sử < p class = "dấu chấm câu"> [

lịch sử

.

length

-

1

]

;

const

vuông

=

hiện tại

.

hình vuông

.

lát

(

)

;

nếu

(

allowWinner

(

hình vuông

)

||

vuông

[

i

]

)

{

trả về

;

}

hình vuông

[

i

]

=

this

.

bang

.

xIsNext

?

'X'

:

'O'

;

this

.

setState

(

{

history

:

history

.

concat

(

[

{

hình vuông

:

vuông

,

}

]

)

,

xIsNext

:

!

this

.

bang

.

xIsNext

, >

}

)

;

}

Lưu ý

Không giống như phương thức array push () mà bạn có thể quen thuộc hơn, phương thức concat () không thay đổi mảng ban đầu, vì vậy chúng tôi thích nó hơn.

Tại thời điểm này, thành phần Board chỉ cần các phương thức renderSquare kết xuất . Phương thức handleClick phải nằm trong thành phần Trò chơi

Không có gì giống như một nụ cười trên khuôn mặt của bạn

Hiển thị các chuyển động trong quá khứ

Vì chúng tôi đang ghi lại lịch sử của trò chơi tic-tac-toe nên giờ đây chúng tôi có thể hiển thị nó cho người chơi dưới dạng danh sách các nước đi trong quá khứ

Chúng ta đã biết trước đó rằng các phần tử React là các đối tượng JavaScript hạng nhất; chúng tôi có thể vượt qua chúng trong các ứng dụng của chúng tôi. Để hiển thị nhiều mục trong React, chúng ta có thể sử dụng một mảng các phần tử React.

Trong JavaScript, mảng có phương thức map () là thường được sử dụng để ánh xạ dữ liệu với dữ liệu khác, ví dụ:

 

const

number

=

[

1

,

2

,

3

]

>

;

const

đã nhân đôi

=

number

function "> map

(

x

= & gt; x

*

2

)

;

Sử dụng phương thức map , chúng tôi có thể ánh xạ lịch sử di chuyển của mình tới các phần tử React đại diện cho các nút trên màn hình và hiển thị danh sách trong số các nút để "chuyển" đến các bước di chuyển trước đây

Hãy ánh xạ qua lịch sử trong render :

  

kết xuất

(

)

{

const

history

=

this

.

bang

.

lịch sử

;

const

hiện tại

=

lịch sử

[

lịch sử

.

length

-

1

] p>

;

const

winner

=

CalculWinner

(

hiện tại

.

hình vuông

)

; >

const

di chuyển

=

lịch sử

.

bản đồ

(

(

bước

,

di chuyển

)

= & gt;

{

const

desc

=

move

?

'Chuyển đến bước di chuyển #'

+

di chuyển

:

'Bắt ​​đầu trò chơi'

< p class = "dấu chấm câu">;

return

(

& lt;

li

& gt;

< / p>

Nút

& lt;

onClick

=

{

(

)

= & gt;

cái này

. < / p>

jumpTo

(

move

)

}

& gt;

{

desc

}

& lt; /

nút

& gt;

& lt; / li

& gt;

)

;

}

)

;

để

trạng thái

;

if

(

winner

)

{

status

=

'Người chiến thắng:'

+

Người chiến thắng

;

}

khác

{

status

=

'Trình phát tiếp theo:'

+

(

cái này

.

bang

.

xIsNext

?

'X'

:

< p class = "token string"> 'O'

)

;

}

trả về

(

& lt;

div

className

=

"

trò chơi

"

& gt;

& lt;

div < / p>

className

=

"

game-board

"

& gt;

& lt;

Bảng

ô vuông

=

{

hiện tại

.

hình vuông

}

onClick

=

{

(

i

)

= & gt;

cái này

.

handleClick

(

i

)

}

/ & gt;

& lt; /

div

& gt;

& lt;

div < / p>

className

=

"

game-info

"

& gt;

& lt;

div < / p>

& gt;

{

trạng thái

}

& lt; /

div

& gt ;

& lt;

ol

& gt;

{

di chuyển

}

& lt; /

ol

& gt;

& lt; /

div

& gt;

& lt; /

div

& gt;

)

;

}

Xem toàn bộ mã tại thời điểm này

Khi chúng tôi lặp qua mảng history , biến step tham chiếu đến history giá trị phần tử và move đề cập đến history chỉ mục phần tử. Chúng tôi chỉ quan tâm đến move ở đây, do đó step không được gán cho bất kỳ thứ gì. < / p>

Đối với mỗi bước đi trong lịch sử trò chơi tic-tac-toe, chúng tôi tạo một mục danh sách & lt; li & gt; chứa một nút & lt; nút & gt; . Nút có trình xử lý onClick gọi một phương thức có tên this.jumpTo () . Chúng tôi chưa triển khai phương thức jumpTo () . Hiện tại, chúng ta sẽ thấy danh sách các động thái đã xảy ra trong trò chơi và cảnh báo trong bảng điều khiển công cụ dành cho nhà phát triển có nội dung:

Cảnh báo:
Mỗi phần tử con trong một mảng hoặc trình vòng lặp phải có một chỗ dựa “khóa” duy nhất. Kiểm tra phương thức kết xuất của “Trò chơi”.

Hãy thảo luận về ý nghĩa của cảnh báo trên.

Chọn khóa

Khi chúng tôi hiển thị một danh sách, React sẽ lưu trữ một số thông tin về từng mục trong danh sách được hiển thị. Khi chúng tôi cập nhật danh sách, React cần xác định những gì đã thay đổi. Chúng tôi có thể đã thêm, xóa, sắp xếp lại hoặc cập nhật các mục của danh sách.

Hãy tưởng tượng chuyển đổi từ

  

& lt;

li

& gt;

Alexa: Còn lại 7 nhiệm vụ

& lt; /

li

& gt;

& lt;

li

& gt; < / p>

Ben: Còn 5 nhiệm vụ

& lt; /

li

& gt;

tới

  

& lt;

li

& gt;

Ben: Còn 9 nhiệm vụ

& lt; /

li

& gt;

& lt;

li

& gt; < / p>

Claudia: Còn 8 nhiệm vụ

& lt; /

li

& gt;

& lt;

li

& gt; < / p>

Alexa: Còn 5 tác vụ

& lt; /

li

& gt;

< / code>

Ngoài số lượng được cập nhật, một người đang đọc thông tin này có thể nói rằng chúng tôi đã hoán đổi thứ tự của Alexa và Ben và chèn Claudia vào giữa Alexa và Ben. Tuy nhiên, React là một chương trình máy tính và không biết những gì chúng tôi dự định. Vì React không thể biết được ý định của chúng ta, nên chúng ta cần chỉ định một thuộc tính khóa cho mỗi mục danh sách để phân biệt từng mục danh sách với các anh chị em của nó. Một tùy chọn sẽ là sử dụng các chuỗi alexa , ben , claudia . Nếu chúng tôi đang hiển thị dữ liệu từ cơ sở dữ liệu, thì các ID cơ sở dữ liệu của Alexa, Ben và Claudia có thể được sử dụng làm khóa.

  

& lt;

li

key

=

{user.id}

& gt;

{user.name}: {user.taskCount} nhiệm vụ còn lại

& lt; /

li

& gt;

Khi một danh sách được hiển thị lại, React sẽ lấy khóa của từng mục trong danh sách và tìm kiếm các mục của danh sách trước đó để tìm khóa phù hợp. Nếu danh sách hiện tại có khóa không tồn tại trước đó, thì React sẽ tạo một thành phần. Nếu danh sách hiện tại thiếu khóa tồn tại trong danh sách trước đó, React sẽ hủy thành phần trước đó. Nếu hai phím khớp nhau, thành phần tương ứng sẽ được di chuyển. Các phím cho React biết về danh tính của từng thành phần cho phép React duy trì trạng thái giữa các lần hiển thị. Nếu khóa của thành phần thay đổi, thành phần đó sẽ bị phá hủy và được tạo lại với trạng thái mới.

key là một thuộc tính đặc biệt và dành riêng trong React (cùng với ref , a tính năng nâng cao hơn). Khi một phần tử được tạo, React sẽ trích xuất thuộc tính key và lưu trữ khóa trực tiếp trên phần tử được trả về. Mặc dù key có thể trông giống như nó thuộc về props , key không thể được tham chiếu bằng this.props.key . React tự động sử dụng key để quyết định cập nhật thành phần nào. Một thành phần không thể hỏi về khóa của nó.

Chúng tôi thực sự khuyên bạn nên chỉ định các khóa thích hợp bất cứ khi nào bạn tạo danh sách động. Nếu bạn không có khóa thích hợp, bạn có thể muốn xem xét việc cơ cấu lại dữ liệu của mình.

Nếu không có khóa nào được chỉ định, React sẽ đưa ra cảnh báo và sử dụng chỉ mục mảng làm khóa theo mặc định. Việc sử dụng chỉ mục mảng làm khóa là một vấn đề khi cố gắng sắp xếp lại thứ tự các mục của danh sách hoặc chèn / xóa các mục danh sách. Chuyển rõ ràng key = {i} sẽ làm cảnh báo im lặng nhưng có cùng vấn đề với chỉ số mảng và không được khuyến nghị trong hầu hết các trường hợp.

Các khóa không cần phải là duy nhất trên toàn cầu; chúng chỉ cần là duy nhất giữa các thành phần và anh chị em của chúng.

Triển khai Du hành thời gian

Trong lịch sử trò chơi tic-tac-toe, mỗi nước đi trong quá khứ đều có một ID duy nhất được liên kết với nó: đó là số thứ tự của nước đi. Các bước di chuyển không bao giờ được sắp xếp lại, xóa hoặc chèn vào giữa, vì vậy có thể an toàn khi sử dụng chỉ mục di chuyển làm chìa khóa.

Trong phương thức kết xuất của thành phần Trò chơi, chúng tôi có thể thêm khóa dưới dạng & lt; li key = { move} & gt; và cảnh báo của React về khóa sẽ biến mất:

  

const

di chuyển

= < / p> lịch sử

.

bản đồ

(

(

bước

,

di chuyển

) < / p>

= & gt;

{

const

desc

=

move

?

'Chuyển đến di chuyển #'

+

di chuyển

:

'Bắt ​​đầu trò chơi'

;

trả về

(

& lt;

li

khóa

>

& gt;

& lt;

nút

onClick

=

{

(

)

= & gt;

this

.

jumpTo

(

di chuyển

)

}

& gt ;

{

desc

}

& lt; /

& gt;

& lt; /

li

& gt;

)

;

}

)

;

Không có gì giống như một nụ cười trên khuôn mặt của bạn

Việc nhấp vào bất kỳ nút nào của mục danh sách sẽ gây ra lỗi vì phương thức jumpTo chưa được xác định. Trước khi triển khai jumpTo , chúng tôi sẽ thêm vào trạng thái của thành phần Trò chơi để cho biết chúng tôi hiện đang xem bước nào.

Đầu tiên, thêm vào trạng thái ban đầu trong constructor : của Trò chơi

 

class

Trò chơi

mở rộng

React

.

Thành phần

{

hàm tạo

(

đạo cụ

)

{

super

(

đạo cụ

)

;

this

.

state

=

{

lịch sử

:

[

{

ô vuông

:

Mảng

(

9

)

.

điền

(

rỗng

">)

,

}

]

,

stepNumber

:

0

,

xIsNext

:

true

,

}

;

}

Tiếp theo, chúng ta sẽ xác định phương thức jumpTo trong Trò chơi để cập nhật StepNumber đó. Chúng tôi cũng đặt xIsNext thành true nếu số mà chúng tôi đang thay đổi thành số chẵn:

  

handleClick

(

i

)

{

}

jumpTo

(

bước

)

{

cái này

.

setState

(

{

bước "gatsby-highlight-code-line">

xIsNext

:

(

bước

%

2

)

===

0

,

}

)

;

}

kết xuất

(

)

{

}

Lưu ý rằng trong phương thức jumpTo , chúng tôi chưa đã cập nhật thuộc tính history của tiểu bang. Đó là bởi vì các cập nhật trạng thái được hợp nhất hay nói cách đơn giản hơn là React sẽ chỉ cập nhật các thuộc tính được đề cập trong phương thức setState , giữ nguyên trạng thái còn lại. Để biết thêm thông tin, hãy xem tài liệu .

Bây giờ, chúng tôi sẽ thực hiện một số thay đổi đối với phương thức handleClick của Trò chơi. Phương thức này sẽ kích hoạt khi bạn nhấp vào một hình vuông.

Trạng thái stepNumber mà chúng tôi đã thêm phản ánh chuyển động được hiển thị cho người dùng hiện tại. Sau khi thực hiện một động thái mới, chúng tôi cần cập nhật stepNumber bằng cách thêm stepNumber: history.length là một phần của đối số this.setState . Điều này đảm bảo rằng chúng tôi không gặp khó khăn khi thể hiện cùng một động thái sau khi một động thái mới được thực hiện.

Chúng tôi cũng sẽ thay thế việc đọc this.state.history bằng this.state.history.slice ( 0, this.state.stepNumber + 1) . Điều này đảm bảo rằng nếu chúng ta "quay ngược thời gian" và sau đó thực hiện một bước đi mới từ thời điểm đó, chúng ta sẽ vứt bỏ tất cả lịch sử "tương lai" mà bây giờ sẽ không chính xác.

  

handleClick

(

i

)

{

const

lịch sử

=

this

.

bang

.

lịch sử

.

lát cắt

(

0

,

cái này

.

bang

.

stepNumber

+

1

)

;

const

hiện tại

=

lịch sử

[

lịch sử

.

length

-

1

< p class = "dấu chấm câu">]

;

const

vuông

=

.

vuông

.

lát cắt

(

)

;

nếu

(

CalculWinner

(

ô vuông

)

||

ô vuông

[ i

]

)

{

trả về

;

}

hình vuông

[

i

]

=

this

.

bang

.

xIsNext

?

'X'

:

'O'

;

this

.

setState

(

{

lịch sử

:

lịch sử

.

kết hợp

(

[

{

hình vuông

:

hình vuông

}

]

)

,

stepNumber

:

lịch sử

.

length

,

xIsNext

:

!

cái này

. p> trạng thái

.

xIsNext

,

}

)

;

}

Cuối cùng, chúng tôi sẽ sửa đổi kết xuất của thành phần Trò chơi từ luôn hiển thị bước cuối cùng để hiển thị bước hiện được chọn theo stepNumber :

  

kết xuất

(

)

{

const

history

=

this

.

bang

.

lịch sử

;

const

=

lịch sử

[

cái này

.

bang

. stepNumber

]

;

const

người chiến thắng < p class = "token operator"> =

allowWinner

(

hiện tại

.

hình vuông

)

;

Nếu chúng tôi nhấp vào bất kỳ bước nào trong lịch sử trò chơi, bảng tic-tac-toe sẽ ngay lập tức cập nhật để hiển thị bảng trông như thế nào sau khi bước đó xảy ra

Không có gì giống như một nụ cười trên khuôn mặt của bạn

Kết thúc

Xin chúc mừng! Bạn đã tạo một trò chơi tic-tac-toe:

  • Hãy chơi tic-tac-toe,
  • Cho biết khi nào một người chơi đã thắng trò chơi,
  • Lưu trữ lịch sử trò chơi khi trò chơi diễn ra,
  • Cho phép người chơi xem lại lịch sử trò chơi và xem các phiên bản trước của bảng trò chơi

Bạn làm tốt lắm! Chúng tôi hy vọng bây giờ bạn cảm thấy như bạn đã nắm rõ về cách hoạt động của React.

Xem kết quả cuối cùng tại đây: Kết quả cuối cùng

Nếu bạn có thêm thời gian hoặc muốn thực hành các kỹ năng React mới của mình, đây là một số ý tưởng về những cải tiến mà bạn có thể thực hiện đối với trò chơi tic-tac-toe được liệt kê theo thứ tự độ khó tăng dần:

  1. Hiển thị vị trí của mỗi lần di chuyển theo định dạng (cột, hàng) trong danh sách lịch sử di chuyển
  2. In đậm mục hiện được chọn trong danh sách di chuyển.
  3. Viết lại bảng để sử dụng hai vòng lặp để tạo các hình vuông thay vì mã hóa chúng.
  4. Thêm nút chuyển đổi cho phép bạn sắp xếp các bước di chuyển theo thứ tự tăng dần hoặc giảm dần
  5. Khi ai đó thắng, hãy đánh dấu ba ô vuông đã tạo nên chiến thắng.
  6. Khi không có ai thắng, hãy hiển thị thông báo về kết quả hòa.

Trong suốt hướng dẫn này, chúng tôi đã đề cập đến các khái niệm React bao gồm các phần tử, thành phần, đạo cụ và trạng thái. Để được giải thích chi tiết hơn về từng chủ đề này, vui lòng tham khảo phần còn lại của tài liệu . Để biết thêm thông tin về cách xác định các thành phần, hãy xem React.Component Tham chiếu API


Xem thêm những thông tin liên quan đến chủ đề hướng dẫn phản ứng js cho người mới bắt đầu

Chia sẽ lộ trình học Javascript cho người mới bắt đầu | Anonumous Fpoly

  • Tác giả: Anonymous Fpoly
  • Ngày đăng: 2022-06-11
  • Đánh giá: 4 ⭐ ( 2266 lượt đánh giá )
  • Khớp với kết quả tìm kiếm:

Hướng dẫn dành cho người mới bắt đầu JavaScript

  • Tác giả: nordiccoder.com
  • Đánh giá: 3 ⭐ ( 8997 lượt đánh giá )
  • Khớp với kết quả tìm kiếm:

Unit test là gì – Jest testing NodeJS cho người mới bắt đầu

  • Tác giả: hocweb.vn
  • Đánh giá: 4 ⭐ ( 6473 lượt đánh giá )
  • Khớp với kết quả tìm kiếm: Testing là gì? Làm cách nào để viết một Unit Test cho JavaScript với Jest? Tìm hiểu các kiến ​​thức cơ bản về tes JavaScript với hướng dẫn Jest cho người mới bắt đầu!

Javascript cho người mới bắt đầu – phần 1

  • Tác giả: caodang.fpt.edu.vn
  • Đánh giá: 5 ⭐ ( 7315 lượt đánh giá )
  • Khớp với kết quả tìm kiếm: Cao đẳng FPT Polytechnic tuyển sinh theo hình thức xét tuyển hồ sơ. Tiêu chí đào tạo: Thực học – Thực nghiệp.

ReactJs cho người mới bắt đầu

  • Tác giả: viblo.asia
  • Đánh giá: 5 ⭐ ( 1726 lượt đánh giá )
  • Khớp với kết quả tìm kiếm: *React (còn được gọi là React.js hoặc ReactJS ) là một thư viện JavaScript để xây dựng giao diện người dùng. Nó được duy trì bởi Facebook và một cộng đồng gồm các nhà phát triển và công ty cá nhân. --...

Tài liệu hướng dẫn AngularJS cơ bản cho người mới bắt đầu

  • Tác giả: vn.got-it.ai
  • Đánh giá: 4 ⭐ ( 1013 lượt đánh giá )
  • Khớp với kết quả tìm kiếm: Các tài liệu hướng dẫn AngularJS cơ bản, dễ hiểu sẽ là trợ thủ đắc lực giúp chúng ta có thể làm quen với framework này. Cùng tham khảo các tài liệu này sau đây.

Lập trình JavaScript cho người mới bắt đầu: Các cách học JavaScript

  • Tác giả: vn.bitdegree.org
  • Đánh giá: 5 ⭐ ( 2494 lượt đánh giá )
  • Khớp với kết quả tìm kiếm: Lập trình JavaScript cho người mới bắt đầu: tìm hiểu cách tốt nhất học JavaScript & phát triển sự nghiệp IT qua hướng dẫn lập trình JavaScript này

Xem thêm các bài viết khác thuộc chuyên mục: Kiến thức lập trình

Xem Thêm  Chế độ xem SQL là gì? - cách xem sql

By ads_php