[英]How do you change the state in React on a click event?
New to React and used Create React App to create a simple tic-tac-toe game but running into the following problems: React的新手,并使用Create React App创建了一个简单的井字游戏,但遇到了以下问题:
currentTurn
property doesn't change and it constantly remains X's turn currentTurn
属性不会改变,并且始终保持X的转向 In the below code, if I add a console.log(this.state.board)
to the handleClick()
function the board
array changes but it's all Xs. 在下面的代码中,如果将
console.log(this.state.board)
添加到handleClick()
函数中,则board
数组将更改,但全都是X。 Any ideas? 有任何想法吗?
Here is my App.js: 这是我的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>
);
}
}
My App.css: 我的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;
}
EDIT : Realized I made a dumb mistake by treating this.setState
as an expression instead of a function and wrote incorrect syntax. 编辑 :
this.setState
我通过将this.setState
视为表达式而不是函数来犯了一个愚蠢的错误,并编写了错误的语法。 This works: 这有效:
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
})
There are few problems with your code. 您的代码几乎没有问题。
You shouldn't keep any values in the state if you're not using it inside the render
function. 如果未在
render
函数中使用它,则不应在状态中保留任何值。 In your case, you aren't using PLAYER_ONE_SYMBOL
, PLAYER_TWO_SYMBOL
and currentTurn
inside render
function. 就您而言,您没有在
render
函数中使用PLAYER_ONE_SYMBOL
, PLAYER_TWO_SYMBOL
和currentTurn
。 So you can define them as normal variables in the file or instance variable of the component class. 因此,您可以在组件类的文件或实例变量中将它们定义为普通变量。
setState
is a function. setState
是一个函数。 You can call it by passing changes of state as an object or function which return changes of state as an object. 您可以通过将状态更改作为对象传递或将状态更改作为对象返回的函数来调用它。 Read more about this in official documentation .
在官方文档中阅读有关此内容的更多信息。
You shouldn't mutate the previous state. 您不应该更改先前的状态。 You should always create new object state based on the previous state without mutating it.
您应该始终基于先前的状态创建新的对象状态而不对其进行更改。
So you can change your App component code to something like following to make it work. 因此,您可以将App组件代码更改为类似于以下内容的代码,以使其正常运行。
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>
);
}
}
Notice how I have changed the state using setState
function but without mutating state. 请注意,我如何使用
setState
函数更改状态,但不更改状态。 map
function always returns a new array without modifying/mutating original one. map
函数始终返回一个新数组,而不修改/更改原始数组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.