Skip to content

Commit 5755e5e

Browse files
committed
1st step: Move the game control from Board Component to Game Component.
1 parent 7570339 commit 5755e5e

File tree

1 file changed

+50
-37
lines changed

1 file changed

+50
-37
lines changed

src/index.js

Lines changed: 50 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,64 +3,79 @@ import ReactDOM from 'react-dom';
33
import './index.css';
44

55
class Game extends React.Component {
6-
render() {
7-
return (
8-
<div className="game">
9-
<div className="game-board">
10-
<Board />
11-
</div>
12-
<div className="game-info">
13-
</div>
14-
</div>
15-
);
16-
}
17-
}
18-
19-
20-
class Board extends React.Component {
6+
// Global variables due to avoid to declare in every function.
217
winner;
8+
history;
9+
current;
2210

2311
constructor(props) {
2412
super(props);
2513
this.state = {
26-
squares: Array(9).fill(null),
14+
history: [{
15+
squares: Array(9).fill(null), // Now Board Component will not store the state of the game any more.
16+
}],
2717
xIsNext: true,
28-
};
18+
}
2919
}
3020

31-
handleClick(i) {
32-
const squares = this.state.squares.slice();
33-
if (this.winner || squares[i]) { // If game has ended or square[i] has been already filled, return.
21+
handleClick(i) { /* Due Game Component now have the squares state and Board Component only uses their props this Coponent will
22+
* handleClicks.*/
23+
const squares = this.current.squares.slice();
24+
if (this.winner || squares[i]) {
3425
return;
3526
}
3627
squares[i] = this.state.xIsNext ? 'X' : 'O';
3728
this.setState({
38-
squares: squares,
29+
history: this.history.concat([{
30+
squares: squares,
31+
}]),
3932
xIsNext: !this.state.xIsNext,
4033
});
4134
}
4235

43-
renderSquare(i) {
44-
return (
45-
<Square
46-
value={this.state.squares[i]}
47-
onClick={() => this.handleClick(i)}
48-
/>
49-
);
50-
}
51-
5236
render() {
53-
this.winner = calculateWinner(this.state.squares);
37+
this.history = this.state.history;
38+
this.current = this.history[this.history.length-1];
39+
this.winner = calculateWinner(this.current.squares); // Due Game Component now have the squares state this Component will calculateWinner.
40+
5441
let status;
5542
if (this.winner) {
5643
status = 'Winner: ' + this.winner;
5744
} else {
5845
status = 'Next Player: ' + (this.state.xIsNext ? 'X' : 'O');
5946
}
6047

48+
return (
49+
<div className="game">
50+
<div className="game-board">
51+
<Board
52+
squares={this.current.squares}
53+
onClick={(i) => this.handleClick(i)}
54+
/>
55+
</div>
56+
<div className="game-info">
57+
<div>{status}</div>
58+
</div>
59+
</div>
60+
);
61+
}
62+
}
63+
64+
65+
class Board extends React.Component {
66+
67+
renderSquare(i) {
68+
return (
69+
<Square
70+
value={this.props.squares[i]}
71+
onClick={() => this.props.onClick(i)}
72+
/>
73+
);
74+
}
75+
76+
render() {
6177
return (
6278
<div>
63-
<div className="status">{status}</div>
6479
<div className="board-row">
6580
{this.renderSquare(0)}
6681
{this.renderSquare(1)}
@@ -81,12 +96,10 @@ class Board extends React.Component {
8196
}
8297
}
8398

84-
function Square(props) { /* When a Class only contains a render() method this class can be replaced by a
85-
* function with only one method, render(). This function can get a parameter
86-
* which will be the props. */
99+
function Square(props) {
87100
return (
88-
<button className="square" onClick={props.onClick}> {/* As we are not in a class, we don't need the arrow function to access 'this' */}
89-
{props.value}
101+
<button className="square" onClick={props.onClick}>
102+
{props.value}
90103
</button>
91104
);
92105
}

0 commit comments

Comments
 (0)