時間を巻き戻す
※Reactを学習したい人は「Reactチュートリアル」で学習してみてください。このブログはこのチュートリアルで感じたことや自分のメモを記述していきます。
前回履歴表示が完了した。今回は履歴をクリックするとその時点まで手番が戻るようにする。実装を次の方法で行う。
- 進行中の履歴位置を保持
- 履歴をクリックした時点で履歴位置を更新する
- 履歴位置情報に基づき表示を行う
実装
履歴位置情報stepNumberをコンポーネントGameのコンストラクタで初期化する。
1 2 3 4 5 6 7 8 9 10 11 |
class Game extends React.Component { constructor(props) { super(props); this.state = { history: [{ squares: Array(9).fill(null), }], stepNumber: 0, xIsNext: true, }; } |
履歴がクリックされた際に呼び出す関数jumpToを記述する。これにより履歴情報を更新し時間を巻き戻す。
1 2 3 4 5 6 |
jumpTo(step) { this.setState({ stepNumber: step, xIsNext: (step % 2) === 0, }); } |
4行目は手番情報xIsNext(×か○)を設定している。手番が奇数の場合は×、偶数の場合は○のため、クリックされた際は次の手番(奇数の場合は○、偶数の場合は×)にする必要がある。そこで手番が2で割り切れる場合は、xIsNextにtrue(×)、そうでない場合はfalseで(○)を設定している。
次にマス目をクリックした際に呼び出される関数handleClickを次のように変更する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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) || squares[i]) { return; } squares[i] = this.state.xIsNext ? 'X' : 'O'; this.setState({ history: history.concat([{ squares: squares }]), stepNumber: history.length, xIsNext: !this.state.xIsNext, }); } |
2行目で履歴位置情報stepNumberを基に履歴情報をコピーしている。これにより不要な未来の履歴を除去することになる。
最後に履歴位置情報stepNumberを基に表示するように変更。
1 2 3 4 5 6 7 8 9 10 11 12 |
class Game extends React.Component { ・ ・ ・ render() { const history = this.state.history; const current = history[this.state.stepNumber]; const winner = calculateWinner(current.squares); ・ ・ ・ |
さぁ実行だ
うゎーい、できた!パチパチパチ・・。これでチュートリアルが完成だ!
無事に終了したのだが、少々試してみたいことがある。もう少しだけ続ける。