LoginSignup
0
0

More than 1 year has passed since last update.

【React】公式のチュートリアルをやってみる~④stateのリフトアップ

Last updated at Posted at 2022-06-07

【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が更新される

Squareコンポーネントで、Boardコンポーネントから受け取った表示用の値を表示する

class Square extends React.Component {
  render() {
    return (
      <button 
        className="square" 
        onClick={() => this.props.onClick()}
      >
+       {this.props.value}
      </button>
    );
  }
}
  • 配列squaresのi番目のデータを表示する
    • 現在の状態だと、クリックされていないマスは何も表示されず(null), クリックされたマスはXが表示される

ReactApp5.png

マスを押したらマスに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

参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0