为什么输出显示在Reactjs中的下一个onMouseUp事件中

时间:2017-02-02 11:03:05

标签: javascript html css reactjs

我是ReactJS的新手,这就是我的代码可能没有错误的原因,但我现在不想要这样做。我正在创建一个tic-tac-toe,一切正常,除了那个winner正在更新下一个onMouseUp事件。我到处搜索,但我找不到错误。

我想说的是,当我们玩tic-tac-toe时,获胜的玩家会在获胜时收到警报,但在我的代码中却没有发生。我在className="square"上执行onMouseUp事件之后来了

这是代码。

var Mycheck = React.createClass({
  getInitialState: function() {
    return {
      disppp: "block",
      disppp2: "none",
      cnt: 0,
      active: 1,
      turnNum: 0,
      player: "",
      showWinner: "none"
    }
  },
  handleClick: function(event, key) {
    this.setState({
      cnt: this.state.cnt + 1
    })
    var divId = parseInt(event.target.id);
    var valvar = [];
    if (this.state.active) {
      if (this.state.cnt < 9) {
        this.setState({
          turnNum: this.state.turnNum + 1
        })
        if (this.state.cnt % 2 == 0) {
          valvar[key] = "X";
          this.setState(valvar)
          this.setState({
            disppp: "none",
            disppp2: "block"
          })
        } else {
          valvar[key] = "O";
          this.setState(valvar)
          this.setState({
            disppp: "block",
            disppp2: "none"
          })
        }
      } else {
        alert("GAME DRAW");

      }
    }
    this.Findvalue();

  },
  Findvalue: function() {
    var arr = [];
    var winner;
    var resultant = {
      r1: [1, 2, 3],
      r2: [4, 5, 6],
      r3: [7, 8, 9],
      r4: [1, 4, 7],
      r5: [2, 5, 8],
      r6: [3, 6, 9],
      r7: [1, 5, 9],
      r8: [3, 5, 7]
    };

    for (var i = 1; i < 10; i++) {
      arr[i] = document.getElementById(i).innerHTML;
    }
    if (arr[resultant.r1[0]] == arr[resultant.r1[1]] && arr[resultant.r1[0]] == arr[resultant.r1[2]] && arr[resultant.r1[0]] != "" && arr[resultant.r1[1]] != "" && arr[resultant.r1[2]] != "") {
      winner = arr[resultant.r1[0]];
    }
    if (arr[resultant.r2[0]] == arr[resultant.r2[1]] && arr[resultant.r2[0]] == arr[resultant.r2[2]] && arr[resultant.r2[0]] != "" && arr[resultant.r2[1]] != "" && arr[resultant.r2[2]] != "") {
      winner = arr[resultant.r2[0]];
    }
    if (arr[resultant.r3[0]] == arr[resultant.r3[1]] && arr[resultant.r3[0]] == arr[resultant.r3[2]] && arr[resultant.r3[0]] != "" && arr[resultant.r3[1]] != "" && arr[resultant.r3[2]] != "") {
      winner = arr[resultant.r3[0]];
    }
    if (arr[resultant.r4[0]] == arr[resultant.r4[1]] && arr[resultant.r4[0]] == arr[resultant.r4[2]] && arr[resultant.r4[0]] != "" && arr[resultant.r4[1]] != "" && arr[resultant.r4[2]] != "") {
      winner = arr[resultant.r4[0]];
    }
    if (arr[resultant.r5[0]] == arr[resultant.r5[1]] && arr[resultant.r5[0]] == arr[resultant.r5[2]] && arr[resultant.r5[0]] != "" && arr[resultant.r5[1]] != "" && arr[resultant.r5[2]] != "") {
      winner = arr[resultant.r5[0]];
    }
    if (arr[resultant.r6[0]] == arr[resultant.r6[1]] && arr[resultant.r6[0]] == arr[resultant.r6[2]] && arr[resultant.r6[0]] != "" && arr[resultant.r6[1]] != "" && arr[resultant.r6[2]] != "") {
      winner = arr[resultant.r6[0]];
    }
    if (arr[resultant.r7[0]] == arr[resultant.r7[1]] && arr[resultant.r7[0]] == arr[resultant.r7[2]] && arr[resultant.r7[0]] != "" && arr[resultant.r7[1]] != "" && arr[resultant.r7[2]] != "") {
      winner = arr[resultant.r7[0]];
    }
    if (arr[resultant.r8[0]] == arr[resultant.r8[1]] && arr[resultant.r8[0]] == arr[resultant.r8[2]] && arr[resultant.r8[0]] != "" && arr[resultant.r8[1]] != "" && arr[resultant.r8[2]] != "") {
      winner = arr[resultant.r8[0]];
    }

    if (winner == "X") {
      this.setState({
        active: 0,
        player: "X",
        showWinner: "block"
      })
      alert("WINNER IS PLAYER 1");
    }
    if (winner == "O") {
      this.setState({
        active: 0,
        player: "O",
        showWinner: "block"
      })
      alert("WINNER IS PLAYER 2");
    }
  },
  render: function() {
    var divVal = "";
    var i = 0;

    return ( < div >
      < div className = "turn_num" > TURN NUMBER: {
        this.state.turnNum + 1
      } < /div>

            <button style={{display:this.state.disppp}}>PLAYER 1 FOR X</button >
      < button style = {
        {
          display: this.state.disppp2
        }
      } > PLAYER 2 FOR O < /button><br/ > < br / >
      < button className = "square"
      id = "1"
      onMouseUp = {
        e => this.handleClick(e, "valvar1")
      }
      disabled = {
        this.state.valvar1
      } > {
        this.state.valvar1
      } < /button>
             <button className="square" id="2" onMouseUp={e => this.handleClick(e,"valvar2")} disabled={this.state.valvar2}>{this.state.valvar2}</button >
      < button className = "square"
      id = "3"
      onMouseUp = {
        e => this.handleClick(e, "valvar3")
      }
      disabled = {
        this.state.valvar3
      } > {
        this.state.valvar3
      } < /button>
            <button className="square clearB" id="4" onMouseUp={e => this.handleClick(e,"valvar4")} disabled={this.state.valvar4}>{this.state.valvar4}</button >
      < button className = "square"
      id = "5"
      onMouseUp = {
        e => this.handleClick(e, "valvar5")
      }
      disabled = {
        this.state.valvar5
      } > {
        this.state.valvar5
      } < /button>
             <button className="square"id="6" onMouseUp={e => this.handleClick(e,"valvar6")} disabled={this.state.valvar6}>{this.state.valvar6}</button >
      < button className = "square clearB"
      id = "7"
      onMouseUp = {
        e => this.handleClick(e, "valvar7")
      }
      disabled = {
        this.state.valvar7
      } > {
        this.state.valvar7
      } < /button>
             <button className="square" id="8" onMouseUp={e => this.handleClick(e,"valvar8")} disabled={this.state.valvar8}>{this.state.valvar8}</button >
      < button className = "square"
      id = "9"
      onMouseUp = {
        e => this.handleClick(e, "valvar9")
      }
      disabled = {
        this.state.valvar9
      } > {
        this.state.valvar9
      } < /button><br/ > < br / > < br / >

      < /div>
 <div className="winnerDetail" style={{display:this.state.showWinner}}>WINNER IS : {this.state.player}</div >
    );

  }
});


ReactDOM.render( < Mycheck / > , document.getElementById("container"));
.square {
  height: 50px;
  width: 50px;
  border: 1px solid black;
  background: none;
  float: left;
  padding: 10px;
  text-align: center;
  font-size: 25px;
  font-weight: bold;
  color: #146fbe;
}
.clearB {
  clear: both;
}
.winnerDetail {
  font-size: 30px;
  font-weight: bold;
  margin-top: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>

1 个答案:

答案 0 :(得分:2)

问题在于您使用setState功能的方式。 setState()操作是异步的,并且为了提高性能而进行批处理。这在docs

中有解释
  

setState()不会立即改变this.state,但会创建挂起状态转换。在调用此方法后访问this.state可能会返回现有值。

     

无法保证对setState的调用进行同步操作,并且可以对调用进行批处理以获得性能提升。

this.state.cnt的值将在this.setState()调用后立即保留上一个值:

handleClick: function(event, key) {
    // if this.state.cnt == 0
    this.setState({
        cnt: this.state.cnt + 1
    })
    console.log(this.state.cnt); // this.state.cnt is still 0
}

您应该重写handleClick以执行某些逻辑,然后最终更改状态:

handleClick: function(event, key) {
    var cnt = this.state.cnt;
    cnt++;
    var turnNum = this.state.turnNum;
    var divId = parseInt(event.target.id);
    var valvar = {};
    if (this.state.active) {
      if (cnt < 9) {
        turnNum++;
        if (cnt % 2 == 0) {
          valvar[key] = "X";
          disppp = "none";
          disppp2 = "block";
        } else {
          valvar[key] = "O";
          disppp = "block";
          disppp2 = "none";
        }
      } else {
        alert("GAME DRAW");
      }
    }
    this.setState({
      cnt: cnt,
      turnNum: turnNum,
      disppp: disppp,
      disppp2: disppp2
    })
    this.Findvalue();
}

我还注意到valvar变量是一个数组。它应该是一个对象。