Reputation: 13
I am relative new to ReactJS and I have some problems with setState.
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import './index.js';
class Square extends React.Component {
constructor(props) {
super(props);
this.state = {
value: null,
xNextPlayer: true
};
}
render() {
return (
<button
className="square"
onClick={ async () => {
console.log(this.state.xNextPlayer);
if(this.state.xNextPlayer === true) {
this.setState({value: 'X'});
} else {
this.setState({value: 'O'});
}
await this.setState({xNextPlayer: !this.state.xNextPlayer});
console.log(this.state.xNextPlayer);
}}
>
{this.state.value}
</button>
);
}
}
class Board extends React.Component {
renderSquare(i) {
return <Square />;
}
render() {
const status = 'Next player: X';
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')
);
**strong text**
The problem now is that xNextPlayer is not updated correctly. When I first click, xNextPlayer is true as it should. Then I want to set it to false. It does this correctly and console logs false. But when I click again, it is again set back to true. The first console log then is true, the second false.
But I want to store the value and be false.
Has anybody a solution?
Upvotes: 0
Views: 59
Reputation: 1167
use this method.i think it will be works.
const handleClick =(xNextPlayerStatus:boolean)=>{
if(xNextPlayerStatus){
this.setState({value: 'X'})
}
else if(!xNextPlayerStatus){
this.setState({value: 'O'})
}}
<button className="square" onClick={()=>handleClick(this.state.xNextPlayer)}>
Upvotes: 0
Reputation: 1218
Look at this sandbox: https://codesandbox.io/s/cool-paper-z8kpu . I copypasted your code (except I changed the initial value of a box to "U") and everything works as expected, and that is:
You need to remember that each box has its own state, the fact that they are all the same component does not mean that they have a shared state.
Upvotes: 2
Reputation: 1106
Firstly, using async/await on the setState
is not a good idea because setState
doesn't return a promise. You have to use the 2nd parameter of the setState
function, which is the callback function (as a Promise), if you want to wait for the new state before updating your xNextPlayer
value.
If you want to check your new xNextPlayer
after updating it in your setState
, get it back from the console.log
in the callback scope.
this.setState({ xNextPlayer: !this.state.xNextPlayer }, () => { console.log(this.state.xNextPlayer) })`
Upvotes: 0