【React】公式のチュートリアルをやってみる~③propsとstate の続きです。
勝利したプレイヤーを判定できるように、9個のマス目の値を1か所で管理します。
親コンポーネントで状態を管理する
Boardコンポーネントにthis.state の初期状態を設定するコンストラクタを追加する
class Board extends React.Component {
// コンストラクタ
+ constructor(props) {
+ super(props);
+ this.state = {
+ squares: Array(9).fill(null),
+ }
+ }
renderSquare(i) {
return <Square value={i}/>;
}
render() {
(略)
}
}
- 9個のスロットにnullが入った配列が生成され、squaresに格納される
- ゲームが進むにつれ、配列の中身にX、Oが入るようにする
- 最初の配列の中身は以下の通り
(9) [null, null, null, null, null, null, null, null, null]
0: null
1: null
2: null
3: null
4: null
5: null
6: null
7: null
8: null
length: 9
BoardコンポーネントからSquareコンポーネントに表示用の値を渡す
class Board extends React.Component {
// コンストラクタ
constructor(props) {
super(props);
this.state = {
squares: Array(9).fill(null),
}
}
renderSquare(i) {
return (
+ <Square value={this.state.squares[i]}/>
);
}
render() {
(略)
}
}
- Squareコンポーネントを呼び出し、そのときに props として
{value: this.state.squares[i]}
を渡す- 配列
squares
のi番目に格納されているデータが渡される
- 配列
Boardコンポーネントでイベントハンドラーを定義してSquareコンポーネントに渡す
class Board extends React.Component {
// コンストラクタ
constructor(props) {
super(props);
this.state = {
squares: Array(9).fill(null),
}
}
+ handleClick(i) {
+ const squares = this.state.squares.slice();
+ squares[i] = 'X';
+ this.setState({squares: squares});
+ }
renderSquare(i) {
return (
<Square
value={this.state.squares[i]}
+ onClick={() => this.handleClick(i)}
/>
);
}
render() {
(略)
}
}
- BoardコンポーネントからSquareコンポーネントに
handleClick
関数を渡す- Reactでは、イベントを表すpropsにはon、イベントを処理するメソッドにはhandleという名前を付けるのが慣習となっている
-
handleClick
では、配列squares
のi番目のデータに対してXを代入し、squaresを更新する- 現在の配列を直接変更するのではなく、
slice()
を使って 配列square
のコピーを作成してから配列を置き換えている- このように、変更を加えた新しいデータのコピーを使ってデータを置き換えることを、イミュータビリティ(immutability; 不変性)という
- 直接データのミューテート(データの書き換え)をしないことで、巻き戻し機能の実装が可能になったり、変更を検出しやすくなるといった利点がある
- 現在の配列を直接変更するのではなく、
子コンポーネントで親コンポーネントから受け取ったオブジェクトを反映する
Squareコンポーネントで、Boardコンポーネントから受け取った関数を実行できるようにする
class Square extends React.Component {
render() {
return (
<button
className="square"
+ onClick={() => this.props.onClick()}
>
{this.state.value}
</button>
);
}
}
- クリックイベントに、受け取った
handleClick
関数を設定する- i番目のマスをクリックしたときに、配列
squares
のi番目にXが代入され、squaresが更新される
- i番目のマスをクリックしたときに、配列
Squareコンポーネントで、Boardコンポーネントから受け取った表示用の値を表示する
class Square extends React.Component {
render() {
return (
<button
className="square"
onClick={() => this.props.onClick()}
>
+ {this.props.value}
</button>
);
}
}
- 配列
squares
のi番目のデータを表示する- 現在の状態だと、クリックされていないマスは何も表示されず(null), クリックされたマスはXが表示される
マスを押したらマスにXが表示されるようになりました~
配列squares
にもXが格納されています。
(9) [null, null, 'X', null, 'X', 'X', null, null, null]
0: null
1: null
2: "X"
3: null
4: "X"
5: "X"
6: null
7: null
8: null
length: 9
参考文献
- https://ja.reactjs.org/tutorial/tutorial.html
- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/Array
- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/fill
- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/slice