Reactで○×ゲームのCPU対戦を作成中です。CPUはユーザが押していないランダムなマスを埋めていく仕様です。
以下のGame.js以外にもBoard.js(マス目を管理する)とSquare.js(1マスずつを管理する)があります。
class Game extends React.Component { constructor(props) { super(props); const type = this.props.line **2; this.state = { history: [ { squares: Array(type).fill(null) } ], stepNumber: 0, xIsNext : true, battle :this.props.battle }; } // クリックする(=1手)の動作 handleClick(i) { const history = this.state.history.slice(0, this.state.stepNumber + 1); const current = history[history.length - 1]; const squares = current.squares.slice(); if (calculateWinner(squares,this.props.line) || squares[i]) {return} squares[i] = this.state.xIsNext ? "X" : "O"; this.setState({ history: history.concat([ { squares: squares, } ]), xIsNext: !this.state.xIsNext, // ここですぐにstateが変更されない stepNumber: history.length, }); // player対戦の場合、あるいはCPU対戦の場合でcpuEasyですでに呼ばれている場合に無限ループしないようにする // 上記でstateがすぐ変更されないため、xIsNext=trueとしてreturnで抜けてしまう if(this.state.battle === "player" || this.state.xIsNext === true){return} this.cpuEasy(i,squares,this.handleClick,this.state.xIsNext); } //CPUのロジック cpuEasy(i,squares,handleClick) { console.log("called!") const l = squares.length; for(var a=0; a<l; a++){ const j = Math.floor(Math.random()*l); if(squares[j]==null || squares[j]!==squares[i]){ this.handleClick(j); //ランダムな値 j でhandleClick()を呼び出す break; } } } // ターンを戻す jumpTo(step) { this.setState({ stepNumber: step, xIsNext: (step % 2) ? false : true, }); } // 画面の描画 render() { const history = this.state.history; const current = history[this.state.stepNumber]; const winner = calculateWinner(current.squares,this.props.line); const xIsNext = this.state.xIsNext; const moves = history.map((step, move) => { const desc = move ? 'Go to move #' + move : 'Go to game start'; const selectedClass = this.state.stepNumber === move ? "bold" : ""; return ( <li key={move}> <button onClick={() => this.jumpTo(move)} className={selectedClass}>{desc}</button> </li> ); }); let status; if (winner) { status = "Winner: " + winner; } else { status = "Next player: " + (this.state.xIsNext ? "X" : "O"); } return ( <div className="game"> <div className="game-board"> <Board squares={current.squares} onClick={i => this.handleClick(i)} line={this.props.line} /> </div> <div className="game-info"> <div>{status}</div> <ol>{moves}</ol> </div> </div> ); } }
・Xを先攻(=ユーザ)、Oを後攻(=CPU)で固定
・state
で{xIsNext:true}
を初期値として持っておく
・クリックされるたびにhandleClick()
で{xIsNext:!this.state.xIsNext}
としてターンを反転させる
というかたちにしています。
###質問
handleClick
のなかで即座にstateを変更するにはどのようにすればいいのでしょうか?
Reactにおけるstateがrender()を呼び出すたびにしか、更新されないということは理解したのですが再レンダリングする方法がわからず、、

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。