简体   繁体   English

如何在点击事件中更改React的状态?

[英]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创建了一个简单的井字游戏,但遇到了以下问题:

  • Cannot get the "X" and "O" to appear in the DOM after clicking in a square 单击正方形后,无法在DOM中显示“ X”和“ O”
  • The 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. 您的代码几乎没有问题。

  1. 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_SYMBOLPLAYER_TWO_SYMBOLcurrentTurn So you can define them as normal variables in the file or instance variable of the component class. 因此,您可以在组件类的文件或实例变量中将它们定义为普通变量。

  2. 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 . 官方文档中阅读有关此内容的更多信息。

  3. 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.

相关问题 REACT——如何改变聚焦/模糊事件的点击状态 - REACT -- How to change the click state of a focused / blurred event 如何在React中将值传递给状态更改回调? - How do you pass a value to a state change callback in React? 如何从不同的组件更改反应组件的 state? - How do you change state of a react component from a different component? 在单击之前如何获得打印 state 的按钮? - How do you get the button to print the state before you click it? 我们如何在另一个组件中单击按钮时更改反应组件中元素的 state? - How do we change the state of element in a react component on button click in another component? React with Hooks:点击事件后如何正确更新状态? - React with Hooks: how to correctly update state after a click event? react中的onClick事件在选择时是否有优先级? 如果是,你如何改变它们? - Does the onClick event in react have priorities while choosing? If yes, how do you change them? 你如何在反应中使用和改变innerHTML? - how do you use and change innerHTML in react? 如何更改同一事件的事件触发顺序? - How do you change the event firing order of the same event? 如何在 onClick 事件期间更改 React 中多个元素的状态 - How to change state on multiple elements in React during onClick event
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM