Tiếp tục với bài trước Bài 14: ReactJs- Viết game caro bằng React hôm nay chúng ta sẽ tiếp tục hoàn thiện game.
Đối với component Square sau khi đã bỏ đi constructor, chúng ta có thể đơn giản hóa nó đi thành một function thay vì class như sau:
function Square(props) {
return (
<button className="square" onClick={props.onClick}>
{props.value}
</button>
);
}
Nếu như 1 component chỉ return về 1 element mà không thực thi function gì chúng ta nên viết theo dạng function, ví dụ như thằng Square trên.Taking Turns
Hiện tại game chúng ta chỉ có thằng X được chơi nên chúng ta sẽ thay đổi 1 tí để thêm nước O.
Trong Board constructor ta thêm 1 state nữa:
class Board extends React.Component {
constructor(props) {
super(props);
this.state = {
squares: Array(9).fill(null),
xIsNext: true,
};
}
Mỗi một nước đi ta sẽ thay đổi xIsNext và thay đổi mảng nước đi squares theo xIsNext:
handleClick(i) {
const squares = this.state.squares.slice();
squares[i] = this.state.xIsNext ? 'X' : 'O';
this.setState({
squares: squares,
xIsNext: !this.state.xIsNext,
});
}
Sau khi X O đã có lượt đi chúng ta cần thay đổi status cho Game:
render() {
const status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
return (
// the rest has not changed
Sau tất cả :)) chúng ta có đoạn code như sau:
class Board extends React.Component {
constructor(props) {
super(props);
this.state = {
squares: Array(9).fill(null),
xIsNext: true,
};
}
handleClick(i) {
const squares = this.state.squares.slice();
squares[i] = this.state.xIsNext ? 'X' : 'O';
this.setState({
squares: squares,
xIsNext: !this.state.xIsNext,
});
}
renderSquare(i) {
return (
<Square
value={this.state.squares[i]}
onClick={() => this.handleClick(i)}
/>
);
}
render() {
const status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
return (
<div>
<div className="status">{status}</div>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className="board-row">
{this.renderSquare(3)}
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
</div>
);
}
}
Declaring a Winner
Tạo 1 function để kiểm tra người thắng, các bạn thêm function này vào cuối file:
function calculateWinner(squares) {
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],
];
for (let i = 0; i < lines.length; i++) {
const [a, b, c] = lines[i];
if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
return squares[a];
}
}
return null;
}
Giờ chúng ta sẽ gọi hàm này trong Board's render để check khi có người nào win và đổi status thành người win X/O. Ta thay đổi status trong Board's render:
render() {
const winner = calculateWinner(this.state.squares);
let status;
if (winner) {
status = 'Winner: ' + winner;
} else {
status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
}
return (
// the rest has not changed
Bây giờ trong handleClick của Board ta xét nếu có người win game hoăc là các ô vuông đều kín thì stop game lại:
handleClick(i) {
const squares = this.state.squares.slice();
if (calculateWinner(squares) || squares[i]) {
return;
}
squares[i] = this.state.xIsNext ? 'X' : 'O';
this.setState({
squares: squares,
xIsNext: !this.state.xIsNext,
});
}
Congratulations! Bạn đã thành công rồi, giờ refresh lại trang và thử chơi game nào!
Có problem gì bạn để lại comment nhá, mình sẽ giải đáp trong vòng 24h.
Hay quá bác. Viết tiếp về react server side rendering bác ơi
Trả lờiXóaThiếu 'Hòa' anh ơi :))
Trả lờiXóa