React官方示例中的小游戏示例

React官方示例中的小游戏示例

示例地址

https://zh-hans.reactjs.org/tutorial/tutorial.html#lifting-state-up

代码(具体的逻辑注解在代码中)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import React from 'react';
import ReactDOM from 'react-dom';

class Square extends React.Component {
render() {
return (
<button
className="square"
// 如果像下面这样写的话,箭头函数其实返回的是一个函数,
// 这个函数就是this.props.onClick()中传入的函数
// 等价于: () => {return this.props.onClick()}
// 也等价于: {this.props.onClick} 注意两边都没有括号.是上面式子的一种简写,用户没有参数的函数
onClick={this.props.onClick}
// onClick={() => {
// console.log(this.props.onClick())
// return this.props.onClick()
// }}
>
{this.props.value}
</button>
);
}
}

// function Square(props){
// return (
// <button
// className="square"
// // 此处也是用了简写方式
// onClick={props.onClick}
// >
// {props.value}
// </button>
// );
// }

class Board extends React.Component {

constructor(props){
super(props)
this.state = {
squares: Array(9).fill(null),
xIsNext: true
}
}

renderSquare(i) {
return (
<Square
value={this.state.squares[i]}
// onClick={() => this.handleClick(i)}
// 通过实验可以知道此处的onClick其实需要传入一个函数的执行而不是函数本身
// handle: undefined
onClick={() => {
console.log('handle:', this.handleClick(i))
return this.handleClick(i)
}}
/>
);
}

handleClick = function (i) {
const squares = this.state.squares.slice();
// squares[i] = 'X';
if(calculateWinner(this.state.squares)) return;
if(squares[i] === null){
squares[i] = this.state.xIsNext ? 'X' : 'O';
this.setState({
squares: squares,
xIsNext: !this.state.xIsNext
});
}
}

render() {
const winner = calculateWinner(this.state.squares);
let status;

if(winner){
status = "Winner:" + winner
}else{
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>
);
}
}

class Game extends React.Component {
render() {
return (
<div className="game">
<div className="game-board">
<Board />
</div>
<div className="game-info">
<div>{/* status */}</div>
<ol>{/* TODO */}</ol>
</div>
</div>
);
}
}

// ========================================

ReactDOM.render(
<Game />,
document.getElementById('root')
);

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

如果你想自己尝试的话:

https://codepen.io/gaearon/pen/oWWQNa?editors=0010

React官方示例中的小游戏示例

https://www.borgor.cn/posts/c07cc943.html

作者

Cyrusky

发布于

2019-11-21

更新于

2024-11-18

许可协议

评论