2017-01-11 4 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 для реагирования в настоящее время. Я бы посмотрел [create-react-app] (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});         
    }    
}, 

вы только обновляете состояние один раз, когда квадрат «_» и никогда больше. Если вы удалите этот оператор if, вы увидите, что ваш счет правильно увеличивается, и знак правильно изменяется.

Тем не менее, решение вашей общей проблемы, не имеющей поворота, меняется, поэтому, когда вы нажимаете квадрат, он поворачивается на X, и когда вы нажимаете на другое, поворачивайтесь на O, можно решить, просто переместив состояние, чей ход вплоть до состояния компонента Board.

+0

мой плохой, исправил его – ElenaDBA

+0

Фактически удаление инструкции if не улучшилось - теперь каждый раз, когда я нажмите на пустую кнопку, я получаю X, и только если я нажму одну и ту же кнопку несколько раз, я получаю O. Поэтому он регистрирует количество кликов на кнопку, а не на плату. Как я могу переместить состояние в компонент Board? – ElenaDBA

+0

Правильно, так что в основном вам нужно отслеживать, чей поворот он находится в вашем состоянии доски, а затем при каждом изменении хода, чей ход. Первый проект, который приходит мне в голову, заключается в добавлении ключа разворота в состояние Правления и его значения 0 или 1, а затем каждый раз, когда вы нажимаете квадрат, инвертируйте его. Чтобы отслеживать, какие квадраты - это то, что у вас может быть простой массив, который соответствует каждому месту в состоянии платы, которое вы обновляете и отправляете каждому компоненту в качестве опоры. Я бы рекомендовал поиграть с ним, так как это лучший способ узнать! – Dibesjr