Html có khó không

Chúng tôi sẽ xây dựng một trò chơi nhỏ trong 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ó một 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ẽ giúp bạn hiểu sâu hơn 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 học 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

  • sẽ cung cấp cho bạn một điểm khởi đầu để làm theo hướng dẫn
  • sẽ dạy cho bạn những nguyên tắc cơ bản của React. thành phần, đạo cụ và trạng thái
  • sẽ dạy cho bạn những kỹ thuật phổ biến nhất trong phát triển React
  • sẽ cung cấp cho bạn cái nhìn sâu sắc hơn về những đ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 ta đang xây dựng cái gì?

Trong hướng dẫn này, chúng tôi sẽ chỉ cho bạn cách xây dựng trò chơi tic-tac-toe tương tác với React

Bạn có thể thấy những gì chúng tôi sẽ xây dựng ở đây. Kết quả cuối cùng. Nếu mã không có ý nghĩa 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 phần hướng dẫn. Một trong những tính năng mà bạn sẽ chú ý là có một danh sách được đánh số ở bên phải bàn cờ 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 nước đi đã xảy ra trong trò chơi và nó được cập nhật khi trò chơi diễn ra

Bạn có thể đóng trò chơi tic-tac-toe khi đã quen với nó. Chúng ta 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ẽ cho rằng bạn đã quen thuộc với HTML và JavaScript, nhưng bạn sẽ có thể theo kịp ngay cả khi bạn đến từ một ngôn ngữ lập trình khác. Chúng tôi cũng giả định 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à 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, câu lệnh

return React.createElement('div', {className: 'shopping-list'},
  React.createElement('h1', /* .. h1 children .. */),
  React.createElement('ul', /* .. ul children .. */)
);
4 và
return React.createElement('div', {className: 'shopping-list'},
  React.createElement('h1', /* .. h1 children .. */),
  React.createElement('ul', /* .. ul children .. */)
);
5. Bạn có thể sử dụng để kiểm tra xem mã ES6 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

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

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

Đầu tiên, hãy mở Starter Code này trong một tab mới. Tab mới sẽ hiển thị một 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

Bây giờ bạn có thể bỏ qua tùy chọn thiết lập thứ hai và chuyển đến phần để có cái nhìn tổng quan về React

Tùy chọn thiết lập 2. Môi trường phát triển địa phương

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


Không bắt buộc. Hướng dẫn theo dõi 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 đòi hỏi 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 bạn có phiên bản Node mới nhất. js đã cài đặt
  2. Thực hiện theo để thực hiện 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
    return React.createElement('div', {className: 'shopping-list'},
      React.createElement('h1', /* .. h1 children .. */),
      React.createElement('ul', /* .. ul children .. */)
    );
    6 của dự án mới

Ghi chú

Không xóa toàn bộ thư mục

return React.createElement('div', {className: 'shopping-list'},
  React.createElement('h1', /* .. h1 children .. */),
  React.createElement('ul', /* .. ul children .. */)
);
7, chỉ xóa các tệp nguồn ban đầu bên trong thư mục đó. Chúng tôi sẽ thay thế các tệp nguồn mặc định bằng các ví dụ cho dự án này trong bước tiếp theo

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. Thêm một tệp có tên
    return React.createElement('div', {className: 'shopping-list'},
      React.createElement('h1', /* .. h1 children .. */),
      React.createElement('ul', /* .. ul children .. */)
    );
    8 trong thư mục
    return React.createElement('div', {className: 'shopping-list'},
      React.createElement('h1', /* .. h1 children .. */),
      React.createElement('ul', /* .. ul children .. */)
    );
    6 với mã CSS này
  2. Thêm một tệp có tên
    class Board extends React.Component {
      renderSquare(i) {
        return <Square value={i} />;  }
    }
    0 trong thư mục
    return React.createElement('div', {className: 'shopping-list'},
      React.createElement('h1', /* .. h1 children .. */),
      React.createElement('ul', /* .. ul children .. */)
    );
    6 với mã JS này
  3. Thêm ba dòng này vào đầu
    class Board extends React.Component {
      renderSquare(i) {
        return <Square value={i} />;  }
    }
    0 trong thư mục
    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';

Bây giờ nếu bạn chạy

class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
4 trong thư mục dự án và mở
class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
5 trong trình duyệt, bạn sẽ thấy một 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 mình

Giúp với, tôi bị kẹt

Nếu bạn gặp khó khăn, hãy xem các tài nguyên hỗ trợ cộng đồng. Đặc biệt, Reactiflux Chat 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 tìm hiểu tổng quan về React

Phản ứng 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 soạn các giao diện người dùng phức tạp từ các đoạn mã nhỏ và biệt lập được gọi là “các thành phần”

React có một vài 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

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

class ShoppingList extends React.Component {
  render() {
    return (
      <div className="shopping-list">
        <h1>Shopping List for {this.props.name}h1>
        <ul>
          <li>Instagramli>
          <li>WhatsAppli>
          <li>Oculusli>
        ul>
      div>
    );
  }
}

// Example usage: 

Chúng ta sẽ sớm đến với các thẻ giống như 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à kết xuất 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à

class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
7 (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
class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
8

Phương thức

class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
8 trả về một mô tả về những gì bạn muốn thấy trên màn hình. React lấy mô tả và hiển thị kết quả. Đặc biệt,
class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
8 trả về một phần tử React, đây là một mô tả đơn giản về nội dung sẽ hiển thị. 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 viết các cấu trúc này dễ dàng hơn. Cú pháp
class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {this.props.value}      button>
    );
  }
}
1 được chuyển đổi tại thời điểm xây dựng thành
class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {this.props.value}      button>
    );
  }
}
2. Ví dụ trên tương đương với

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

Nếu bạn tò mò,

class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {this.props.value}      button>
    );
  }
}
3 được mô tả chi tiết hơn trong phần , nhưng chúng tôi sẽ không 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 qua trong chương trình của mình

Thành phần

class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {this.props.value}      button>
    );
  }
}
4 ở trên chỉ hiển thị các thành phần DOM tích hợp như
class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {this.props.value}      button>
    );
  }
}
1 và
class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {this.props.value}      button>
    );
  }
}
6. Nhưng bạn cũng có thể soạn và kết xuất 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
class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {this.props.value}      button>
    );
  }
}
7. Mỗi thành phần React được đóng gói và có thể hoạt động độc lập;

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

Nếu bạn định làm phần hướng dẫn trong trình duyệt của mình, hãy mở mã này trong một tab mới. Mã bắt đầu. Nếu bạn định thực hiện hướng dẫn cục bộ, thay vào đó hãy mở

class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {this.props.value}      button>
    );
  }
}
8 trong thư mục dự án của bạn (bạn đã chạm vào tệp này trong quá trình thực hiện)

Mã khởi đầu này là cơ sở của những gì chúng tôi đang xây dựng. Chúng tôi đã cung cấp kiểu dáng 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

  • Quảng trường
  • Tấm ván
  • Trò chơi

Thành phần Hình vuông hiển thị một

class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {this.props.value}      button>
    );
  }
}
9 duy nhất và Bảng hiển thị 9 ô 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

Truyền dữ liệu qua Props

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

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 việc thông 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 sâu sắc hơn

Trong phương pháp

class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
0 của Board, hãy thay đổi mã để chuyển một chỗ dựa có tên là
class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
1 cho Square

________số 8_______

Thay đổi phương thức

class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
8 của Square để hiển thị giá trị đó bằng cách thay thế
class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
3 bằng
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>
    );
  }
}

Trước

Html có khó không

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

Html có khó không

Xem mã đầy đủ 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 Board gốc sang thành phần Square con. Truyền đạo cụ là cách thông tin chảy trong ứng dụng React, từ cha mẹ sang con cái

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

Hãy điền vào thành phần Square bằng một chữ “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

class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
5 của thành phần Square thành cái này

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

Nếu bạn nhấp vào Square ngay bây giờ, bạn sẽ thấy 'nhấp chuột' trong bảng điều khiển devtools của trình duyệt của bạn

Ghi chú

Để tiết kiệm việc nhập và tránh hành vi khó hiểu của

class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
6, chúng tôi sẽ sử dụng cú pháp hàm mũi tên cho trình xử lý sự kiện tại đây và thêm bên dưới

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

Lưu ý cách với

class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
7, chúng tôi đang chuyển một hàm dưới dạng chỗ dựa của
class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
8. React sẽ chỉ gọi chức năng này sau một cú nhấp chuột. Quên
class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
9 và viết
class Square extends React.Component {
 render() {
   return (
     <button className="square" onClick={() => console.log('click')}>       {this.props.value}
     button>
   );
 }
}
0 là một lỗi phổ biến và sẽ kích hoạt mỗi khi thành phần kết xuất lại

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

Các thành phần phản ứng có thể có trạng thái bằng cách đặt

class Square extends React.Component {
 render() {
   return (
     <button className="square" onClick={() => console.log('click')}>       {this.props.value}
     button>
   );
 }
}
1 trong hàm tạo của chúng.
class Square extends React.Component {
 render() {
   return (
     <button className="square" onClick={() => console.log('click')}>       {this.props.value}
     button>
   );
 }
}
1 nên được coi là riêng tư đối với thành phần React mà nó được xác định trong. Hãy lưu trữ giá trị hiện tại của Square trong
class Square extends React.Component {
 render() {
   return (
     <button className="square" onClick={() => console.log('click')}>       {this.props.value}
     button>
   );
 }
}
1 và thay đổi giá trị đó khi Square được nhấp vào

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

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>
    );
  }
}

Ghi chú

Trong các lớp JavaScript, bạn cần luôn gọi

class Square extends React.Component {
 render() {
   return (
     <button className="square" onClick={() => console.log('click')}>       {this.props.value}
     button>
   );
 }
}
4 khi định nghĩa hàm tạo của một lớp con. Tất cả các lớp thành phần React có
class Square extends React.Component {
 render() {
   return (
     <button className="square" onClick={() => console.log('click')}>       {this.props.value}
     button>
   );
 }
}
5 nên bắt đầu bằng lệnh gọi
class Square extends React.Component {
 render() {
   return (
     <button className="square" onClick={() => console.log('click')}>       {this.props.value}
     button>
   );
 }
}
6

Bây giờ chúng ta sẽ thay đổi phương thức

class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
8 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ế
    class Square extends React.Component {
     render() {
       return (
         <button className="square" onClick={() => console.log('click')}>       {this.props.value}
         button>
       );
     }
    }
    8 bằng
    class Square extends React.Component {
     render() {
       return (
         <button className="square" onClick={() => console.log('click')}>       {this.props.value}
         button>
       );
     }
    }
    9 bên trong thẻ
    class Square extends React.Component {
      render() {
        return (
          <button className="square">
            {this.props.value}      button>
        );
      }
    }
    9
  • Thay thế trình xử lý sự kiện
    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 bằng
    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
  • Đặt các đạo cụ
    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 và
    class Square extends React.Component {
      render() {
        return (
          <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
          button>
        );
      }
    }
    8 trên các dòng riêng biệt để dễ đọc hơn

Sau những thay đổi này, thẻ

class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {this.props.value}      button>
    );
  }
}
9 được trả về bởi phương thức
class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
8 của Square trông như thế này

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

Bằng cách gọi

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 từ trình xử lý
class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
8 trong phương thức
class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
8 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 nhấp vào
class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {this.props.value}      button>
    );
  }
}
9 của nó. Sau khi cập nhật,
class Square extends React.Component {
 render() {
   return (
     <button className="square" onClick={() => console.log('click')}>       {this.props.value}
     button>
   );
 }
}
9 của Square sẽ là
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, vì vậy chúng ta sẽ thấy
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 trên bảng trò chơi. Nếu bạn nhấp vào bất kỳ Hình vuông nào, một
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 sẽ xuất hiện

Khi bạn gọi

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 trong một thành phần, React cũng sẽ tự động cập nhật các thành phần con bên trong nó

Xem mã đầy đủ tại thời điểm này

Những công cụ phát triển

Tiện ích mở rộng React Devtools dành cho Chrome và 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

Html có khó không

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 dưới dạng các tab cuối cùng của trang . Sử dụng “⚛️ Thành phần” để kiểm tra cây thành phần

Tuy nhiên, lưu ý rằng có một vài 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” và sau đó chọn “Chế độ gỡ lỗi”
  4. Trong tab mới mở ra, devtools bây giờ sẽ có tab React

Hoàn thành trò chơi

Bây giờ chúng ta đã 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 luân phiên đặt 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 Nhà Nước Lên

Hiện tại, mỗi thành phần Square duy trì trạng thái của trò chơi. Để kiểm tra người chiến thắng, chúng tôi sẽ duy trì giá trị của mỗi 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 Square về trạng thái của Square. 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ó cấu trúc lại. Thay vào đó, cách tiếp cận tốt nhất là lưu trữ trạng thái của trò chơi trong thành phần Bảng gốc thay vì trong mỗi Ô vuông. Thành phần Board có thể cho mỗi Square biết nội dung sẽ hiển thị bằng cách chuyển một chỗ dựa,

Để 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, thay vào đó, bạn cần khai báo trạng thái chia sẻ trong thành phần cha của chúng. Thành phần cha mẹ có thể chuyển trạng thái trở lại thành phần con bằng cách sử dụng đạo cụ;

Việc nâng trạng thái thành một thành phần chính là phổ biến khi các thành phần React được tái cấu trúc - 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 giá trị rỗng tương ứng với 9 ô vuông

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

Khi chúng ta điền vào bảng sau, mảng

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 sẽ giống như thế này

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

Phương pháp

class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
0 của Hội đồng quản trị hiện tại giống như thế này

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

Ban đầu, chúng tôi từ Bảng để hiển thị các số từ 0 đến 8 trong mỗi Ô 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”. Đây là lý do tại sao Square hiện đang bỏ qua

class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
1 chỗ dựa được Hội đồng chuyển cho nó

Bây giờ chúng ta sẽ sử dụng lại cơ chế truyền prop. Chúng tôi sẽ sửa đổi Hội đồng quản trị để hướng dẫn từng Square riêng lẻ về giá trị hiện tại của nó (

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 hoặc
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). Chúng tôi đã xác định mảng
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 trong hàm tạo của Board và chúng tôi sẽ sửa đổi phương thức của Board
class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
0 để đọc từ nó

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

Xem mã đầy đủ tại thời điểm này

Mỗi ô vuông bây giờ sẽ nhận được một giá đỡ

class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
1 sẽ là
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 hoặc
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 cho các ô vuông trống

Tiếp theo, chúng ta cần thay đổi điều gì sẽ xảy ra khi nhấp vào Hình vuông. Thành phần Board hiện duy trì ô vuông nào được lấp đầy. Chúng ta 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 một thành phần xác định nó, nên chúng tôi không thể cập nhật trạng thái của Bảng trực tiếp từ Square

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

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

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

Ghi chú

Chúng tôi chia phần tử được 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

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 và làm hỏng mã của chúng tôi

Bây giờ chúng tôi đang chuyển hai đạo cụ từ Board sang Square.

class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
1 và
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 là một chức năng mà Square có thể gọi khi nhấp vào. Chúng tôi sẽ thực hiện các thay đổi sau đối với Square

  • Thay thế
    class Square extends React.Component {
     render() {
       return (
         <button className="square" onClick={() => console.log('click')}>       {this.props.value}
         button>
       );
     }
    }
    9 bằng
    class Square extends React.Component {
     render() {
       return (
         <button className="square" onClick={() => console.log('click')}>       {this.props.value}
         button>
       );
     }
    }
    8 trong phương thức
    class Board extends React.Component {
      renderSquare(i) {
        return <Square value={i} />;  }
    }
    8 của Square
  • Thay thế
    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 bằng
    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 trong phương thức
    class Board extends React.Component {
      renderSquare(i) {
        return <Square value={i} />;  }
    }
    8 của Square
  • Xóa
    class Square extends React.Component {
     render() {
       return (
         <button className="square" onClick={() => console.log('click')}>       {this.props.value}
         button>
       );
     }
    }
    5 khỏi Square vì Square không còn theo dõi trạng thái của trò chơi nữa

Sau những thay đổi này, thành phần Square trông như thế này

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

Khi nhấp vào Ô vuông, chức năng

class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
8 do Hội đồng cung cấp được gọi là. Đây là một đánh giá về cách đạt được điều này

  1. Prop
    class Square extends React.Component {
      render() {
        return (
          <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
          button>
        );
      }
    }
    8 trên thành phần DOM
    class Square extends React.Component {
      render() {
        return (
          <button className="square">
            {this.props.value}      button>
        );
      }
    }
    9 tích hợp yêu cầu 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
    class Square extends React.Component {
      render() {
        return (
          <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
          button>
        );
      }
    }
    8 được định nghĩa trong phương thức
    class Square extends React.Component {
      render() {
        return (
          <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
          button>
        );
      }
    }
    5 của Square
  3. Trình xử lý sự kiện này gọi
    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. Chỗ dựa
    class Square extends React.Component {
      render() {
        return (
          <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
          button>
        );
      }
    }
    8 của Square đã được chỉ định bởi Hội đồng
  4. Vì Hội đồng đã chuyển
    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 cho Square, nên Square gọi là
    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 của Hội đồng khi nhấp vào
  5. Chúng tôi chưa xác định phương pháp
    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, vì vậy mã của chúng tôi bị lỗi. Nếu bây giờ bạn nhấp vào một ô vuông, 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”

Ghi chú

Thuộc tính

class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
8 của phần tử DOM
class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {this.props.value}      button>
    );
  }
}
9 có ý nghĩa đặc biệt đối với React vì nó là một thành phần 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 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 pháp
class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
8 của Square hoặc phương pháp
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 của Hội đồng quản trị và mã sẽ hoạt động như nhau. Trong React, thông thường sẽ sử dụng tên
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 cho các đạo cụ đại diện cho các sự kiện và
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 cho các phương thức xử lý các sự kiện

Khi chúng tôi 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

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. Bây giờ chúng ta sẽ thêm
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 vào lớp Board

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

Xem mã đầy đủ 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 Ô vuông để điền vào 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, nên 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à các thành phần được kiểm soát. Hội đồng quản trị có toàn quyền kiểm soát họ

Lưu ý cách trong

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, chúng tôi gọi
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 để tạo một bản sao của mảng
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 để sửa đổi thay vì sửa đổi mảng hiện có. Chúng tôi sẽ giải thích tại sao chúng tôi tạo một bản sao của mảng
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 trong phần tiếp theo

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

Trong ví dụ mã trước, chúng tôi khuyên bạn nên tạo một bản sao của mảng

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 bằng cách sử dụng phương thức
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 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à tại sao tính bất biến lại quan trọng để học

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 tiếp cận thứ hai là thay thế dữ liệu bằng một bản sao mới có các thay đổi mong muốn

Thay đổi dữ liệu với đột biến

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

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

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

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ử của trò chơi tic-tac-toe và “quay lại” các nước đi 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 một số hành động nhất định là yêu cầu phổ biến trong các ứng dụng. Việc tránh thay đổi dữ liệu trực tiếp cho phép chúng tôi giữ nguyê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

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. 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 được duyệt qua

Phát hiện các thay đổi trong các đối tượng bất biến dễ dàng hơn nhiều. 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 kết xuất lại trong React

Lợi ích chính của tính không thay đổi 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, điều này giúp xác định khi nào một thành phần yêu cầu kết xuất lại

Bạn có thể tìm hiểu thêm về

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 và cách bạn có thể xây dựng các thành phần thuần túy bằng cách đọc

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

Bây giờ chúng ta sẽ thay đổi Square thành một thành phần chức năng

Trong React, các thành phần chức năng là một cách đơn giản hơn để viết các thành phần chỉ chứa phương thức

class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
8 và không có trạng thái riêng. Thay vì định nghĩa một lớp mở rộng
class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
6, chúng ta có thể viết một hàm lấy
class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
7 làm đầu vào và trả về kết quả sẽ được hiển thị. Các thành phần chức năng ít tẻ nhạt hơn để 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 chức năng này

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

Chúng tôi đã thay đổi

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 thành
class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
7 cả hai lần nó xuất hiện

Xem mã đầy đủ tại thời điểm này

Ghi chú

Khi chúng tôi sửa đổi Square thành một thành phần chức năng, chúng tôi cũng đã thay đổi

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 thành
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 ngắn hơn (lưu ý thiếu dấu ngoặc đơn ở cả hai bên)

Thay phiên nhau

Bây giờ chúng ta cần sửa một lỗi rõ ràng trong trò chơi tic-tac-toe của mình. chữ “O” không thể được đánh dấu trên bảng

Chúng tôi sẽ đặt nước đi đầu tiên là “X” theo mặc định. 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 hàm tạo Board của chúng tôi

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

Mỗi khi một người chơi di chuyển,

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 (một 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 lại. Chúng tôi sẽ cập nhật hàm
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 của Hội đồng quản trị để lật giá trị của
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

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

Chúng ta cũng hãy thay đổi văn bản "trạng thái" trong Bảng

class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
8 để nó hiển thị người chơi nào có lượt tiếp theo

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

Sau khi áp dụng những thay đổi này, bạn sẽ có thành phần Bảng này

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

Xem mã đầy đủ tại thời điểm này

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

Bây giờ chúng tôi hiển thị lượt của người chơi tiếp theo, 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 nữa. Sao chép chức năng trợ giúp này và dán vào cuối tệp

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

Đưa ra một mảng gồm 9 ô vuông, hàm này sẽ kiểm tra người chiến thắng và trả về

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 hoặc
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 nếu thích hợp

Chúng tôi sẽ gọi

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 trong chức năng
class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
8 của Hội đồng để kiểm tra xem người chơi có thắng không. Nếu một người chơi đã thắng, chúng tôi có thể hiển thị văn bản chẳng hạn như “Người chiến thắng. X” hoặc “Người chiến thắng. Ô”. Chúng ta sẽ thay thế khai báo
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 trong hàm
class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
8 của Board bằng mã này

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

Giờ đây, chúng tôi có thể thay đổi chức năng

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 của Bàn cờ để về sớm bằng cách bỏ qua nhấp chuột nếu ai đó đã thắng trò chơi hoặc nếu Ô vuông đã được lấp đầy

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

Xem mã đầy đủ 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

Thêm du hành thời gian

Bài tập cuối cùng, hãy tạo khả năng “quay ngược thời gian” về các nước đi trước đó trong trò chơi

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

Nếu chúng ta thay đổi mảng

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, việc thực hiện du hành thời gian sẽ rất khó khăn

Tuy nhiên, chúng tôi đã sử dụng

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 để tạo một bản sao mới của mảng
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 sau mỗi lần di chuyển và. Đ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
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 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

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 trước đây trong một mảng khác có tên là
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. Mảng
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 đại diện cho tất cả các trạng thái của bàn cờ, từ nước đi đầu tiên đến nước đi cuối cùng và có dạng như thế này

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

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

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

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

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 để làm điều đó, vì vậy chúng tôi sẽ đặt trạng thái
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 trong thành phần Trò chơi cấp cao nhất

Đặt trạng thái

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 vào thành phần Trò chơi cho phép chúng tôi xóa trạng thái
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 khỏi thành phần Bảng con của nó. Giống như chúng tôi từ thành phần Square thành thành phần Board, chúng tôi hiện đang nâng nó từ thành phần Board lên thành phần Game cấp cao nhất. Điều này cung cấp cho thành phần Trò chơi toàn quyền kiểm soát dữ liệu của Hội đồng và cho phép nó hướng dẫn Hội đồng hiển thị các lượt trước đó từ
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

Đầu tiên, chúng ta 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ó

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

Tiếp theo, chúng ta sẽ yêu cầu thành phần Hội đồng quản trị nhận các đạo cụ

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 và
class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
8 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 Squares, nên chúng tôi sẽ cần chuyển vị trí của từng Squares vào trình xử lý
class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
8 để cho biết Square nào đã được nhấp vào. Dưới đây là các bước cần thiết để chuyển đổi thành phần Board

  • Xóa
    class Square extends React.Component {
     render() {
       return (
         <button className="square" onClick={() => console.log('click')}>       {this.props.value}
         button>
       );
     }
    }
    5 trong Bảng
  • Thay thế
    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 bằng
    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 trong Hội đồng quản trị của
    class Square extends React.Component {
      render() {
        return (
          <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
          button>
        );
      }
    }
    0
  • Thay thế
    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 bằng
    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 trong Hội đồng quản trị của
    class Square extends React.Component {
      render() {
        return (
          <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
          button>
        );
      }
    }
    0

Thành phần Board bây giờ trông như thế này

class ShoppingList extends React.Component {
  render() {
    return (
      <div className="shopping-list">
        <h1>Shopping List for {this.props.name}h1>
        <ul>
          <li>Instagramli>
          <li>WhatsAppli>
          <li>Oculusli>
        ul>
      div>
    );
  }
}

// Example usage: 
0

Chúng tôi sẽ cập nhật chức năng

class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
8 của thành phần Trò chơi để sử dụng mục nhập lịch sử gần đây nhất nhằm xác định và hiển thị trạng thái của trò chơi

class ShoppingList extends React.Component {
  render() {
    return (
      <div className="shopping-list">
        <h1>Shopping List for {this.props.name}h1>
        <ul>
          <li>Instagramli>
          <li>WhatsAppli>
          <li>Oculusli>
        ul>
      div>
    );
  }
}

// Example usage: 
1

Vì thành phần Trò chơi hiện đang hiển thị trạng thái của trò chơi, nên chúng tôi có thể xóa mã tương ứng khỏi phương thức

class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
8 của Hội đồng quản trị. Sau khi tái cấu trúc, hàm
class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
8 của Board trông như thế này

class ShoppingList extends React.Component {
  render() {
    return (
      <div className="shopping-list">
        <h1>Shopping List for {this.props.name}h1>
        <ul>
          <li>Instagramli>
          <li>WhatsAppli>
          <li>Oculusli>
        ul>
      div>
    );
  }
}

// Example usage: 
2

Cuối cùng, chúng ta cần chuyển phương thức

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 từ thành phần Board sang thành phần Trò chơi. Chúng tôi cũng cần sửa đổi
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 vì trạng thái của thành phần Trò chơi được cấu trúc khác. Trong phương pháp
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 của Trò chơi, chúng tôi nối các mục lịch sử mới vào
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>Instagramli>
          <li>WhatsAppli>
          <li>Oculusli>
        ul>
      div>
    );
  }
}

// Example usage: 
3

Ghi chú

Không giống như phương pháp mảng

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
05 mà bạn có thể quen thuộc hơn, phương pháp
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
06 không làm thay đổi mảng ban đầu, vì vậy chúng tôi thích phương pháp này hơn

Tại thời điểm này, thành phần Hội đồng quản trị chỉ cần các phương pháp

class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
0 và
class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
8. Trạng thái của trò chơi và phương thức
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 phải có trong thành phần Trò chơi

Xem mã đầy đủ tại thời điểm này

Hiển thị các bước di chuyển trong quá khứ

Vì chúng tôi đang ghi lại lịch sử của trò chơi tic-tac-toe, 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ứ

Trước đó chúng ta đã biết rằng các phần tử React là các đối tượng JavaScript hạng nhất; . Để kết xuất 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

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
10 thường được sử dụng để ánh xạ dữ liệu sang dữ liệu khác, chẳng hạn

class ShoppingList extends React.Component {
  render() {
    return (
      <div className="shopping-list">
        <h1>Shopping List for {this.props.name}h1>
        <ul>
          <li>Instagramli>
          <li>WhatsAppli>
          <li>Oculusli>
        ul>
      div>
    );
  }
}

// Example usage: 
4

Sử dụng phương thức

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
11, chúng ta có thể lập bản đồ 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 các nút để “nhảy” tới các bước di chuyển trước đây

Hãy

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
11 vượt qua
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 trong phương pháp
class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
8 của Trò chơi

class ShoppingList extends React.Component {
  render() {
    return (
      <div className="shopping-list">
        <h1>Shopping List for {this.props.name}h1>
        <ul>
          <li>Instagramli>
          <li>WhatsAppli>
          <li>Oculusli>
        ul>
      div>
    );
  }
}

// Example usage: 
5

Xem mã đầy đủ tại thời điểm này

Khi chúng ta lặp qua mảng

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, biến
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
16 đề cập đến giá trị phần tử
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 hiện tại và
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
18 đề cập đến chỉ số phần tử
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 hiện tại. Chúng tôi chỉ quan tâm đến
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
18 ở đây, do đó,
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
16 không được chỉ định cho bất kỳ thứ gì

Đối với mỗi lần di chuyển trong lịch sử của trò chơi tic-tac-toe, chúng tôi tạo một mục danh sách

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
22 có chứa một nút
class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {this.props.value}      button>
    );
  }
}
9. Nút này có trình xử lý
class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>        {this.props.value}
      button>
    );
  }
}
8 gọi phương thức có tên là
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
25. Chúng tôi chưa triển khai phương pháp
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
26. Hiện tại, chúng ta sẽ thấy danh sách các nước đi đã xảy ra trong trò chơi và một cảnh báo trong bảng điều khiển công cụ dành cho nhà phát triển cho biết

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 "chì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 một chìa khóa

Khi chúng tôi kết xuất một danh sách, React sẽ lưu trữ một số thông tin về từng mục danh sách được kết xuất. 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 trong danh sách

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

class ShoppingList extends React.Component {
  render() {
    return (
      <div className="shopping-list">
        <h1>Shopping List for {this.props.name}h1>
        <ul>
          <li>Instagramli>
          <li>WhatsAppli>
          <li>Oculusli>
        ul>
      div>
    );
  }
}

// Example usage: 
6

đến

class ShoppingList extends React.Component {
  render() {
    return (
      <div className="shopping-list">
        <h1>Shopping List for {this.props.name}h1>
        <ul>
          <li>Instagramli>
          <li>WhatsAppli>
          <li>Oculusli>
        ul>
      div>
    );
  }
}

// Example usage: 
7

Ngoài số lượng được cập nhật, một người đọc điều này có thể sẽ 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 chúng tôi dự định làm gì. Vì React không thể biết ý định của chúng tôi, chúng tôi cần chỉ định thuộc tính khóa cho từng mục danh sách để phân biệt từng mục danh sách với anh chị em của nó. Một tùy chọn sẽ là sử dụng các chuỗi

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. Nếu chúng tôi đang hiển thị dữ liệu từ cơ sở dữ liệu, ID cơ sở dữ liệu của Alexa, Ben và Claudia có thể được sử dụng làm khóa

class ShoppingList extends React.Component {
  render() {
    return (
      <div className="shopping-list">
        <h1>Shopping List for {this.props.name}h1>
        <ul>
          <li>Instagramli>
          <li>WhatsAppli>
          <li>Oculusli>
        ul>
      div>
    );
  }
}

// Example usage: 
8

Khi một danh sách được hiển thị lại, React lấy khóa của từng mục 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 chưa tồn tại trước đó, React sẽ tạo một thành phần. Nếu danh sách hiện tại thiếu một 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 kết xuất lại. Nếu khóa của một thành phần thay đổi, thành phần đó sẽ bị hủy và được tạo lại với trạng thái mới

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
30 là một thuộc tính đặc biệt và dành riêng trong React (cùng với
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
31, một tính năng nâng cao hơn). Khi một phần tử được tạo, React trích xuất thuộc tính
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
30 và lưu trữ khóa trực tiếp trên phần tử được trả về. Mặc dù
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
30 có thể trông giống như nó thuộc về
class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
7, nhưng không thể tham chiếu
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
30 bằng cách sử dụng
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
36. React tự động sử dụng
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
30 để 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ề
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
30 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 tái cấu trúc dữ liệu của mình để thực hiện

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. Sử dụng chỉ mục mảng làm khóa có 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 trong danh sách. Chuyển hoàn toàn

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
39 sẽ tắt tiếng cảnh báo nhưng có cùng vấn đề với chỉ mục 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;

Thực hiện du hành thời gian

Trong lịch sử trò chơi tic-tac-toe, mỗi lần di chuyển trong quá khứ 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 sẽ an toàn khi sử dụng chỉ mục di chuyển làm khóa

Trong phương thức

class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
8 của thành phần Trò chơi, chúng ta có thể thêm khóa dưới dạng
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
41 và cảnh báo của React về các khóa sẽ biến mất

class ShoppingList extends React.Component {
  render() {
    return (
      <div className="shopping-list">
        <h1>Shopping List for {this.props.name}h1>
        <ul>
          <li>Instagramli>
          <li>WhatsAppli>
          <li>Oculusli>
        ul>
      div>
    );
  }
}

// Example usage: 
9

Xem mã đầy đủ tại thời điểm này

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

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
42 không được xác định. Trước khi chúng tôi triển khai
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
42, chúng tôi sẽ thêm
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
44 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

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
45 vào trạng thái ban đầu trong trò chơi
class Square extends React.Component {
 render() {
   return (
     <button className="square" onClick={() => console.log('click')}>       {this.props.value}
     button>
   );
 }
}
5

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

Tiếp theo, chúng ta sẽ xác định phương thức

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
42 trong Trò chơi để cập nhật
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
44 đó. Chúng tôi cũng đặt
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 thành true nếu số mà chúng tôi đang thay đổi
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
44 thành số chẵn

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

Lưu ý trong phương pháp

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
42, chúng tôi chưa cập nhật tài sản
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 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 một cách đơn giản hơn, React sẽ chỉ cập nhật các thuộc tính được đề cập trong phương thức
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 để lại trạng thái còn lại như hiện tại. để biết thêm thông tin

Bây giờ, chúng tôi sẽ thực hiện một số thay đổi đối với phương pháp

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 của Trò chơi sẽ kích hoạt khi bạn nhấp vào một ô vuông

Trạng thái

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
44 mà chúng tôi đã thêm phản ánh động thái được hiển thị cho người dùng ngay bây giờ. Sau khi chúng tôi thực hiện một động thái mới, chúng tôi cần cập nhật
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
44 bằng cách thêm
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
57 như một phần của đối số
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. Điều này đảm bảo chúng tôi không gặp khó khăn khi hiển thị cùng một nước đi sau khi một nước đi mới được thực hiện

Chúng tôi cũng sẽ thay thế đọc

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
59 bằng
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
60. Đ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 đó, thì 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

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

Cuối cùng, chúng tôi sẽ sửa đổi phương thức

class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  }
}
8 của thành phần Trò chơi từ luôn hiển thị nước đi cuối cùng thành hiển thị nước đi hiện được chọn theo
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

Nếu chúng ta 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

Xem mã đầy đủ tại thời điểm này

kết thúc

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

  • Cho phép bạn chơi tic-tac-toe,
  • Cho biết khi một người chơi đã thắng trò chơi,
  • Lưu trữ lịch sử của 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

công việc tốt đẹp. Chúng tôi hy vọng bây giờ bạn cảm thấy như bạn đã hiểu rõ về cách thức hoạt động của React

Kiểm tra kết quả cuối cùng ở đâ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 Phản ứng mới của mình, đây là một số ý tưởng để cải thiện trò chơi tic-tac-toe mà bạn có thể thực hiện được liệt kê theo thứ tự độ khó tăng dần

  1. Hiển thị vị trí cho mỗi lần di chuyển ở định dạng (col, row) trong danh sách lịch sử di chuyển
  2. In đậm mục đang đượ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 hình vuông thay vì mã hóa cứng chúng
  4. Thêm nút chuyển đổi cho phép bạn sắp xếp các nước đi 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 dẫn đến chiến thắng
  6. Khi không có ai thắng thì hiển thị thông báo kết quả là 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 yếu 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, hãy xem phần còn lại của tài liệu. Để tìm hiểu thêm về cách xác định các thành phần, hãy xem tài liệu tham khảo API

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