判定
※Reactを学習したい人は「Reactチュートリアル」で学習してみてください。このブログはこのチュートリアルで感じたことや自分のメモを記述していきます。
ここまでマス目をクリックすると×印が表示されるところまで実装してきた。三目並べにするためには×、○を交互に表示しなければいけないし、終了判定も必要だ。まずはこの終了判定を実装する。
終了は縦、横、斜めに○か×が3つ並ぶか、全てのマス目が埋め尽くされた時だ。前回マス目の状態をコンポーネントSquareのstate.valueに保存した。これを上位コンポーネントのBoardから読み出せば簡単に実装できそうだ。
ところが、チュートリアルによるとコンポーネントBoardからSquareの値を取得するのはコードがわかりにくく危険なので勧められていない。ではどうするか・・・。
リフトアップ
対応として各Squareで管理していたクリック情報をBoardで集中管理する。オブジェクト指向的な考えからするとオブジェクトの状態をそのオブジェクトの外で管理するのは違和感があるが、素直に従うとする。そしてBoardからSquareを呼び出す際に対応するクリック情報を受け渡し、Square側で表示するという流れだ。
ソースを変更していく。まずBoardのコンストラクタに9つのマス目に対応するstateを定義する。
1 2 3 4 5 6 7 8 9 10 |
class Board extends React.Component { constructor(props) { super(props); this.state = { squares: Array(9).fill(null), }; } ・ ・ ・ |
stateのキー「squares」を配列で9つの箱を作成し、nullを設定する。さらにメソッドrenderSquareを次にように変更する。
1 2 3 4 5 6 7 8 9 |
renderSquare(i) { return <Square value={i} />; } //次のコードに変更 renderSquare(i) { return <Square value={this.state.squares[i]} />; } |
Squareを呼び出す際に変数valueに定義したstate.squaresの該当する配列の値を設定する。この受け渡された値をSquareで表示すればいいわけだ。
問題発生
Boardでクリック情報を集中管理することにより終了判定できそうだ。だがーー、ここで問題がある。クリックするとコンポーネントSquareが実行される。このクリックされた情報をBoardに知らせる必要が出てきたのだ!
SquareからBoardのstateにアクセスするのは難しいそうだ・・どう解決するか・・・。