質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

7468閲覧

ReactでsetStateをすぐに反映させる方法…

ShowGoTagami

総合スコア13

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2018/09/01 08:00

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()を呼び出すたびにしか、更新されないということは理解したのですが再レンダリングする方法がわからず、、

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

setStateの動作は「複数のsetStateをまとめて、一気に描画する」などの事情があるため、非同期で行われます(リファレンス)。

Think of setState() as a request rather than an immediate command to update the component.

「反映されてからコンピューターの思考を開始したい」のであれば、componentDidUpdateから呼び出すのが適切ではないかと思います。

投稿2018/09/01 10:16

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問