2017-01-11 62 views
-1

我正在学习React并构建井字游戏。 我的代码如下:反应js this.setState无法正常工作

var Square = React.createClass({ 
     getInitialState: function() { 
      return { mark: this.props.mark, 
       clicks: 0 
      }; 
     }, 

     respondToClick: function() {  
      if(this.state.mark == '_') {  
       var nextClick = this.state.clicks + 1; 

      } 
      var newMark = nextClick%2 ? 'X' : 'O';     
       this.setState({mark: newMark, clicks: nextClick});    
     }, 
     render: function(){ 
       return (<button className="square" onClick={this.respondToClick}> 
       {this.state.mark} 
       </button> 
       ); 
     } 
    }); 

    var Board = React.createClass({ 

     renderSquare: function(i) { 
       return (<Square mark='_' />); 
     }, 
     getInitialState: function() { 
      return { 
       clicks: 0 
      }; 
     }, 
     changeValue: function(i, val) { 
       return (<Square value={val} />); 
     }, 
     render: function() { 
       const status = 'Next player: X'; 
       return (
        <div> 
         <div className="status">{status}</div> 
         <div className="board-row"> 
          {this.renderSquare(0)} 
          {this.renderSquare(1)} 
          {this.renderSquare(2)} 
         </div> 
         <div className="board-row"> 
          {this.renderSquare(3)} 
          {this.renderSquare(4)} 
          {this.renderSquare(5)} 
         </div> 
         <div className="board-row"> 
          {this.renderSquare(6)} 
          {this.renderSquare(7)} 
          {this.renderSquare(8)} 
         </div> 
        </div> 
       ); 
     } 

    }); 

    var Game = React.createClass({ 
     render: function() { 
       return (
        <div className="game"> 
         <div className="game-board"> 
          <Board /> 
         </div> 
         <div className="game-info"> 
          <div>{/* status */}</div> 
          <ol>{/* TODO */}</ol> 
         </div> 
        </div> 
       ); 
     } 
    }) 

    ReactDOM.render(
      <Game />, 
      document.getElementById('container') 
    ); 

在我Square组件我有respondToClick方法和方法内我有:

this.setState({mark: newMark, clicks: nextClick}); 

嗯,不知何故没有标志,也没有点击得到更新。我可以使用回调,但在我的情况下,我不明白我该怎么做...任何人都可以请帮忙吗?

+0

作为一个无关的侧面说明,建议现在使用ES6语法进行反应。我会检查[创建 - 反应 - 应用程序](https://github.com/facebookincubator/create-react-app) – Dibesjr

回答

1

问题是,您正在存储您的状态,因为它的层次结构太低。

现在你拥有了它,这样当你点击一个空方,则增加的点击数为1,然后设置方形的标记为X.这不会在此功能,因为更改

respondToClick: function() {  
    if(this.state.mark == '_') {  
     var nextClick = this.state.clicks + 1; 
     var newMark = nextClick%2 ? 'X' : 'O';     
     this.setState({mark: newMark, clicks: nextClick});         
    }    
}, 

当广场是'_'时,您只更新状态一次,永远不会。如果您删除该语句,您将看到您的计数正确增量并且标记正确更改。

但是,当你点击一个方块变成X时,你没有转身的整体问题的解决方案发生变化,当你点击另一个时,它转向O可以通过移动它的状态来解决直至委员会组件的状态。

+0

我的坏,修复它 – ElenaDBA

+0

实际上删除if语句并没有让它变得更好 - 现在每次我点击空按钮我得到一个X,并且只有当我重复点击同一个按钮时,我才会得到一个O.因此它注册每个按钮的点击次数而不是每个板子。如何将状态移动到Board组件? – ElenaDBA

+0

好的,所以基本上你需要跟踪哪个轮到你的棋盘状态,然后每次轮换轮到它。第一个想到的就是在主板的状态下添加一个转向键,并将其设置为0或1,然后每次单击一个正方形时将其反转。为了跟踪哪些方块是什么,你可以有一个简单的数组,与板子状态中的每个点匹配,以便更新并作为道具发送到每个组件。我会建议玩它,因为这是学习的最佳方式! – Dibesjr