@@ -3,64 +3,79 @@ import ReactDOM from 'react-dom';
3
3
import './index.css' ;
4
4
5
5
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.
21
7
winner ;
8
+ history ;
9
+ current ;
22
10
23
11
constructor ( props ) {
24
12
super ( props ) ;
25
13
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
+ } ] ,
27
17
xIsNext : true ,
28
- } ;
18
+ }
29
19
}
30
20
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 ] ) {
34
25
return ;
35
26
}
36
27
squares [ i ] = this . state . xIsNext ? 'X' : 'O' ;
37
28
this . setState ( {
38
- squares : squares ,
29
+ history : this . history . concat ( [ {
30
+ squares : squares ,
31
+ } ] ) ,
39
32
xIsNext : ! this . state . xIsNext ,
40
33
} ) ;
41
34
}
42
35
43
- renderSquare ( i ) {
44
- return (
45
- < Square
46
- value = { this . state . squares [ i ] }
47
- onClick = { ( ) => this . handleClick ( i ) }
48
- />
49
- ) ;
50
- }
51
-
52
36
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
+
54
41
let status ;
55
42
if ( this . winner ) {
56
43
status = 'Winner: ' + this . winner ;
57
44
} else {
58
45
status = 'Next Player: ' + ( this . state . xIsNext ? 'X' : 'O' ) ;
59
46
}
60
47
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 ( ) {
61
77
return (
62
78
< div >
63
- < div className = "status" > { status } </ div >
64
79
< div className = "board-row" >
65
80
{ this . renderSquare ( 0 ) }
66
81
{ this . renderSquare ( 1 ) }
@@ -81,12 +96,10 @@ class Board extends React.Component {
81
96
}
82
97
}
83
98
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 ) {
87
100
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 }
90
103
</ button >
91
104
) ;
92
105
}
0 commit comments