Full React code.
class Square extends React.Component{
render(){
const letters = this.props.print;
const print = letters === 0 ? "" : letters;
return(
<div>
<button className='boxes' onClick={this.props.onClick}>
{print}
</button>
</div>
);
}
}
class Game extends React.Component{
constructor(props){
super(props);
this.handleClick = this.handleClick.bind(this);
this.state = {
letter: 'O',
gameWon: false,
letterArr: [0,0,0,0,0,0,0,0,0],
winArr: [
'X,X,X,0,0,0,0,0,0',
'0,0,0,X,X,X,0,0,0',
'0,0,0,0,0,0,X,X,X',
'X,0,0,X,0,0,X,0,0',
'0,X,0,0,X,0,0,X,0',
'0,0,X,0,0,X,0,0,X',
'X,0,0,0,X,0,0,0,X',
'0,0,X,0,X,0,X,0,0',
'O,O,O,0,0,0,0,0,0',
'0,0,0,O,O,O,0,0,0',
'0,0,0,0,0,0,O,O,O',
'O,0,0,O,0,0,O,0,0',
'0,O,0,0,O,0,0,O,0',
'0,0,O,0,0,O,0,0,O',
'O,0,0,0,O,0,0,0,O',
'0,0,O,0,O,0,O,0,0'
]
};
}
componentDidUpdate(){
let o_s = this.state.letterArr.map((o) => {return o == 'X' ? 0 : o}).toString();
let x_x = this.state.letterArr.map((x) => {return x == 'O' ? 0 : x}).toString();
let oWin = (this.state.winArr.indexOf(o_s) != -1);
let xWin = (this.state.winArr.indexOf(x_x) != -1);
if( oWin == true ){
console.log("O WINS!!!");
board(gameVar.mode, gameVar.letter);
}else if( xWin == true ){
console.log("X WINS!!!");
board(gameVar.mode, gameVar.letter);
}
}
handleClick(i){
let letter = this.state.letter;
let arr = this.state.letterArr.slice();
let change = this.state.letter == "O" ? "X" : "O";
arr[i] = letter;
this.setState({letter: change});
this.setState({letterArr: arr});
}
squares(i){
if(this.state.letterArr[i] == 0){
return(
<Square
print={this.state.letterArr[i]}
onClick={() => {this.handleClick(i)}}
/>
);
}else{
return(
<Square
print={this.state.letterArr[i]}
/>
);
}
}
render(){
return(
<div className='justify'>
{this.squares(0)}
{this.squares(1)}
{this.squares(2)}
{this.squares(3)}
{this.squares(4)}
{this.squares(5)}
{this.squares(6)}
{this.squares(7)}
{this.squares(8)}
</div>
);
}
}
ReactDOM.render(
<Game />,
document.getElementById('root')
);
}
My issue is handleClick updates the constructor and then componentDidUpdate fires, calling Board()
. I was expecting setState inside handleClick
to re-render my class Box
first.
board()
after Box updates with new props? Link to full code: https://codepen.io/xcidis/pen/qVPoME?editors=0011
There are a number of problems with your code. In the render
method on your Game
component you are calling the method Box()
, but that method does not return any value. Even if it did you would need to make some changes since I assume you want multiple boxes to render. Also the Box()
method on your Game
component doesn't take any value as an argument, but you are calling it with a number.
In your Box
component you are extracting the const num
from the property print
, but print
is not passed to the component from the Game
component.
There are a bunch of other problems as well... I suppose this isn't the complete code so didn't bother writing up all the issues.
componentDidUpdate(){
let o_s = this.state.letterArr.map((o) => {return o == 'X' ? 0 : o}).toString();
let x_x = this.state.letterArr.map((x) => {return x == 'O' ? 0 : x}).toString();
let oWin = (this.state.winArr.indexOf(o_s) != -1);
let xWin = (this.state.winArr.indexOf(x_x) != -1);
if( oWin == true ){
//confetti();
setTimeout(function(){
alert('O WINN!!!')
board(gameVar.mode, gameVar.letter)
}, 3000);
}else if( xWin == true ){
//confetti();
setTimeout(function(){
alert('X WINS!!!')
board(gameVar.mode, gameVar.letter)
}, 3000);
}
}
Apparently setState
and componentDidUpdate
are asynchronous. I used setTimeout
to pause setState
->
componentDidUpdate
firing before my component rendered.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.