React的新手并使用Create React App创建一个简单的井字游戏,但遇到了以下问题:
currentTurn
属性不会改变,并且它始终保持X轮流在下面的代码中,如果我向console.log(this.state.board)
函数添加handleClick()
,board
数组会发生变化,但它都是X。有什么想法吗?
这是我的App.js:
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor(props) {
super(props)
this.state = {
PLAYER_ONE_SYMBOL: "X",
PLAYER_TWO_SYMBOL: "O",
currentTurn: "X",
board: [
"", "", "", "", "", "", "", "", ""
]
}
}
handleClick(index) {
var this_board = this.state.board;
this_board[index] = this.state.currentTurn;
this.setState = ({
board: this.state.board,
currentTurn: this.state.currentTurn === this.state.PLAYER_ONE_SYMBOL ? this.state.PLAYER_TWO_SYMBOL : this.state.PLAYER_ONE_SYMBOL
})
}
render() {
return (
<div className="board">
{this.state.board.map((cell, index) => {
return <div onClick={() => this.handleClick(index)} className="square">{cell}</div>;
})}
</div>
);
}
}
我的App.css:
.board {
display: flex;
width: 600px;
height: 600px;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
}
.square {
display: flex;
height: 200px;
width: 200px;
box-sizing: border-box;
border: 5px solid black;
font-size: 5em;
justify-content: center;
align-items: center;
}
.square:hover {
cursor: pointer;
background-color: #80cd92;
}
编辑:意识到我通过将this.setState
视为表达式而不是函数并写入了错误的语法而犯了一个愚蠢的错误。这有效:
this.setState({
board: this.state.board,
currentTurn: this.state.currentTurn === this.state.PLAYER_ONE_SYMBOL ? this.state.PLAYER_TWO_SYMBOL : this.state.PLAYER_ONE_SYMBOL
})
答案 0 :(得分:1)
您的代码几乎没有问题。
如果您未在render
函数中使用该值,则不应保留该状态中的任何值。在您的情况下,您没有在PLAYER_ONE_SYMBOL
函数中使用PLAYER_TWO_SYMBOL
,currentTurn
和render
。因此,您可以将它们定义为组件类的文件或实例变量中的常规变量。
setState
是一个功能。您可以通过将状态更改作为对象或函数传递来调用它,该对象或函数将状态更改作为对象返回。请在official documentation。
你不应该改变以前的状态。您应该始终根据之前的状态创建新的对象状态,而不要改变它。
因此,您可以将应用程序组件代码更改为以下内容,以使其正常工作。
import React, { Component } from "react";
import { render } from "react-dom";
import "./App.css";
const PLAYER_ONE_SYMBOL = "X";
const PLAYER_TWO_SYMBOL = "O";
class App extends Component {
constructor(props) {
super(props);
this.state = {
board: ["", "", "", "", "", "", "", "", ""]
};
this.currentTurn = PLAYER_ONE_SYMBOL;
}
handleClick(index) {
this.setState({
board: this.state.board.map(
(val, boardIndex) => (boardIndex === index ? this.currentTurn : val)
)
});
this.currentTurn =
this.currentTurn === PLAYER_ONE_SYMBOL
? PLAYER_TWO_SYMBOL
: PLAYER_ONE_SYMBOL;
}
render() {
return (
<div className="board">
{this.state.board.map((cell, index) => {
return (
<div onClick={() => this.handleClick(index)} className="square">
{cell}
</div>
);
})}
</div>
);
}
}
注意我是如何使用setState
函数更改状态但没有改变状态。 map
函数总是返回一个新数组而不修改/改变原始数组。