I decided to learn React and started with the official tutorial. All is good until I get to this state of my code. The problem seems to be about property squares of current in the render function of Game component which is defined but I'm not sure why it's flagged as an error
function Square(props){
return (
<button className = "square" onClick = {() => props.onClick()}>
{props.value}
</button>
);
}
class Board extends React.Component {
renderSquare(i) {
return <Square value = {this.props.squares[i]} onClick = {() => this.props.onClick(i)} />;
}
render() {
return (
<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 {
constructor() {
super();
this.state = {
history : [{
squares : Array(9).fill(null)
}],
xIsNext : true
};
}
handleClick(i){
const history = this.state.history.slice(0, this.state.stepNumber);
const current = history[this.state.stepNumber];
const squares = current.squares.slice();
if(calculateWinner(squares) || squares[i]) {
return;
}
squares[i] = this.state.xIsNext ? 'X' : 'O';
this.setState({
history : history.concat([{
squares : squares
}]),
xIsNext : !this.state.xIsNext,
stepNumber : 0,
});
}
jumpTo(step){
this.setState({
stepNumber : step,
xIsNext : (step % 2) ? false : true,
});
}
render() {
const history = this.state.history;
const current = history[this.state.stepNumber];
const winner = calculateWinner(current.squares);
let status;
if(winner) {
status = 'Winner : ' + winner;
}
else {
status = 'Next Player : ' + (this.state.xIsNext ? 'X' : 'O');
}
const moves = history.map((step, move) => {
const desc = move ? 'Move #' + move : 'Game start';
return (
<li key = {move}>
<a href="#" onClick={() => this.jumpTo(move)}>{desc}</a>
</li>
);
});
return (
<div className="game">
<div className="game-board">
<Board
squares = {current.squares}
onClick = {(i) => this.handleClick(i)}
/>
</div>
<div className="game-info">
<div>{status}</div>
<ol>{moves}</ol>
</div>
</div>
);
}
}
// ========================================
ReactDOM.render(
<Game />,
document.getElementById('container')
);
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;
}
And this is the error I get
TypeError: Cannot read property 'squares' of undefined
at Game.render (pen.js:208:41)
at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js:6336:34)
at ReactCompositeComponentWrapper._renderValidatedComponent (https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js:6356:32)
at ReactCompositeComponentWrapper.wrapper [as _renderValidatedComponent] (https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js:12879:21)
at ReactCompositeComponentWrapper.mountComponent (https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js:5969:30)
at ReactCompositeComponentWrapper.wrapper [as mountComponent] (https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js:12879:21)
at Object.mountComponent (https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js:13613:35)
at ReactCompositeComponentWrapper.mountComponent (https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js:5974:34)
at ReactCompositeComponentWrapper.wrapper [as mountComponent] (https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js:12879:21)
at Object.mountComponent (https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js:13613:35)
stepNumber : 0to thestateinside theconstructorof theGamecomponent ?