2017-02-19 1 views
2

私はreact.jsには新しく、簡単なTic-Tac Toeアプリケーションを作成しようとしましたが、私のロジックに問題があります。tic-tac-toe reactjsを使った論理と構文

私は現在のターン、console.logに正しい "X"または "O"文字タイルを持っています。しかし、console.logをrender()関数の中に置くと、反対の文字タイルが返されます(つまり、勝者が "X"の場合、勝者は "O"としてテンプレート上にレンダリングされます)。

render()関数の中で現在の値の値を入れ替えようとしましたが、エラーが出ます。私がここで間違っていることに関するアイデアは?

私のgithubリポジトリへのリンクはこちら、またはコードのチェックアウトは以下のとおりです。 https://github.com/jchan922/tic-react-toe/blob/master/src/App.js

ありがとうございます!

EDIT:

  • CodePen

    からhttp://codepen.io/jchan922/pen/LxKEwm?editors=0010

  • 質問解明

    - 私の論理はコンソルであるにもかかわらず、勝者が「X」であれば、勝者はビューを「O」としてレンダリングし、その逆も同様です。正しい "X"または "O"プレーヤーをレンダリングするためのテンプレートを取得できません。

enter image description here

class App extends Component { 
    // Component Initialization 
    constructor(props){ 
     super(props) 
     this.state = { 
      player_one: "X", 
      player_two: "O", 
      currentTurn: "X", 
      board: [ 
       "", "", "", "", "", "", "", "", "" 
      ], 
      winner: null, 
      moveCount: 0 
     } 
    } 

    handleClick(index){ 
     if(this.state.board[index] === "" && !this.state.winner) { 
      var currentBoard = this.state.board, 
       count = this.state.moveCount; 

      currentBoard[index] = this.state.currentTurn; 
      count += 1; 

      this.setState({ 
       board: this.state.board, 
       winner: this.checkForWinner(), 
       currentTurn: this.state.currentTurn === this.state.player_one ? this.state.player_two : this.state.player_one, 
       moveCount: count 
      }); 

     } 
    } 

    handleReset(){ 
     console.log("RESET") 
     this.setState({ 
      player_one: "X", 
      player_two: "O", 
      currentTurn: "X", 
      board: [ 
       "", "", "", "", "", "", "", "", "" 
      ], 
      winner: null, 
      moveCount: 0 
     }) 
    } 

    checkForWinner(moveCount) { 
     var currentTurn = this.state.currentTurn; 
     var symbols = this.state.board; 
     var winningCombos = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]]; 

     return winningCombos.find(function(combo) { 
      if(symbols[combo[0]] !== "" && symbols[combo[1]] !== "" && symbols[combo[2]] !== "" && symbols[combo[0]] === symbols[combo[1]] && symbols[combo[1]] === symbols[combo[2]]) { 
       console.log("Found a winner", currentTurn, [combo[0],combo[1],combo[2]]); 
       return currentTurn; 
      } 
      else { 
       return null; 
      } 

     }) 
    } 

    // Component Render 
    render() { 
     console.log(this.state.currentTurn); 
     return (
      <div className="app-container"> 
       {this.state.winner ? <h2>{`The winner is ${this.state.currentTurn}`}</h2> : null} 
       <div className="board"> 
        {this.state.board.map((cell, index) => { 
         return <div onClick={() => this.handleClick(index)} key={index} className="square"><p className="playerSymbol">{cell}</p></div> 
        })} 
       </div> 
       <div className="reset"> 
        <button onClick={() => this.handleReset()} className="resetButton">RESET</button> 
       </div> 
      </div> 
     ) 
    } 
} 
export default App; 
+0

どうしますか? – Chris

+0

@Chris私のロジックはどこでも正しくロギングされていますが、勝者が "X"の場合、勝者はテンプレートを "O"としてレンダリングします。 – justinchanman

+0

ああ、ちょっと見てみましょう。実際に、それをコードブックで掴むことができますか?デバッグが容易になります – Chris

答えて

1

まず、あなたは時々、私が持っていることを好む場合には、あなたが「O」としてplayer_oneを持ちたい、ただの定数として、それらを持って、あなたの状態でplayer_oneplayer_twoを必要としません最初にプレイする人を制御し、親コンポーネントにそれらを処理させるブール値の小道具です(Appがレンダリングする唯一のコンポーネントではありませんが、最初のUIを再生するものはUIでは表示されません)。

第2にmoveCountがレンダリングされていないのはなぜですか?多分後でレンダリングを追加したいと思うかもしれません。

は、今すぐあなたの問題に、「X」、のは、それは「X」のターンだというふりをして、プレイヤーが勝利のクリックをクリックしたことを聞かせて勝ったが、最後の文this.setState(...)currentturnがあるthis.state.player_oneに等しい前にクリックして、あなたの​​機能を発射することを前に、 「X」が、あなたはこれを行う:

状態は今、あなたのレンダリングには、 currentturn='O'とUIの再表示を変更したため、その後、「currentturnがXであるならば、そうでない場合はXに設定し、Oに設定してください」という意味
this.setState({... , currentturn : this.state.currentturn === this.state.player_one ? this.state.player_two : this.state.player_one,...}); 

関数the winner is {currentturn}を入れてthe winner is Oをレンダリングします。

解決方法は簡単です。ちょうど{currentturn}{currentturn===player_one ? player_two : player_one}に置き換えてください。これは、勝者を宣言した場合にのみ変更してください。

ここにcodepenが更新されました:http://codepen.io/abnud1/pen/KajpWN?editors=0010

+0

ありがとう!あなたは最初の2つの点で正しいです。しかし、この解決策はXだけではなく、Oではうまくいくように思えます。私は非常に反応しているので、レンダリングセクションでこのロジックを実行するのがベストプラクティスですか?私はまた、handleClick()メソッド内で注文が重要かどうかを調べるために、this.setState({...})のいくつかのキーを移動しようとしましたが、何も起こりませんでした。 – justinchanman

+0

@justinchanmanそれは 'あまりにも'と一緒に働いた、上記のcodepenを見ることができます – niceman

+0

キーの順序は重要ではない、それは反応しない、それはjavascriptのベストプラクティスとしてUIライブラリですが、これはUIロジックなので、この種のロジックのレンダリングのための場所は、我々がリアクト(ビジネスロジックの範囲外)であるロジックについて話すことができるものは – niceman

関連する問題