Javascript 如何更改“对单击事件作出反应”中的状态?

Javascript 如何更改“对单击事件作出反应”中的状态?,javascript,reactjs,jsx,create-react-app,Javascript,Reactjs,Jsx,Create React App,新的反应,用于创建一个简单的井字游戏,但遇到以下问题: 单击正方形后,无法使“X”和“O”显示在DOM中 currentTurn属性不会更改,并且始终保持X的轮到 在下面的代码中,如果我向handleClick()函数添加console.log(this.state.board),则board数组会发生变化,但都是Xs。有什么想法吗 这是我的App.js: import React, { Component } from 'react'; import './App.css'; class

新的反应,用于创建一个简单的井字游戏,但遇到以下问题:

  • 单击正方形后,无法使“X”和“O”显示在DOM中
  • currentTurn
    属性不会更改,并且始终保持X的轮到
在下面的代码中,如果我向
handleClick()
函数添加
console.log(this.state.board)
,则
board
数组会发生变化,但都是Xs。有什么想法吗

这是我的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>
    );
  }
}
EDIT:意识到我犯了一个愚蠢的错误,将
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
})

您的代码几乎没有问题

  • 如果未在
    render
    函数中使用任何值,则不应将其保留在状态中。在您的情况下,您没有使用
    PLAYER\u ONE\u SYMBOL
    PLAYER\u TWO\u SYMBOL
    currentTurn
    内部的
    渲染
    功能。因此,您可以将它们定义为组件类的文件或实例变量中的普通变量

  • setState
    是一个函数。您可以通过将状态更改作为对象传递或将状态更改作为对象返回的函数来调用它。请在中阅读更多关于此的信息

  • 你不应该改变以前的状态。您应该始终基于前一个状态创建新的对象状态,而不会对其进行修改

  • 因此,您可以将应用程序组件代码更改为以下内容,以使其正常工作

    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>
        );
      }
    }
    
    import React,{Component}来自“React”;
    从“react dom”导入{render};
    导入“/App.css”;
    const PLAYER_ONE_SYMBOL=“X”;
    const PLAYER_TWO_SYMBOL=“O”;
    类应用程序扩展组件{
    建造师(道具){
    超级(道具);
    此.state={
    电路板:[,,,,,,,,,,,,,,,,,]
    };
    this.currentTurn=PLAYER\u ONE\u符号;
    }
    handleClick(索引){
    这是我的国家({
    董事会:this.state.board.map(
    (val,boardIndex)=>(boardIndex==索引?this.currentTurn:val)
    )
    });
    现在轮到你了=
    this.currentTurn==PLAYER\u ONE\u符号
    ?玩家两个符号
    :播放器\一个\符号;
    }
    render(){
    返回(
    {this.state.board.map((单元格,索引)=>{
    返回(
    this.handleClick(index)}className=“square”>
    {cell}
    );
    })}
    );
    }
    }
    

    请注意,我是如何使用
    setState
    函数更改状态的,但没有改变状态
    map
    函数始终返回一个新数组,而不修改/变异原始数组。

    发生此行为是因为您正在变异
    This.state
    This.setState
    是一个函数。您需要传递对象,而不是为其赋值。所以
    this.setState=({board:this.state.blah})
    应该是
    this.setState({board:this.state.blah})
    @norbertpy这应该是一个答案而不是注释:)@Kunukn,没人有时间了。@norbertpy刚刚意识到我在语法上犯了一个愚蠢的错误,在我的问题中添加了一个编辑,感谢您在这里解释正确的React编码模式!
    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>
        );
      }
    }