Reactコンポーネント間の値の受け渡し

# この記事の目的
公式チュートリアルで三目並べを作ってもらうのが一番理解できるが、その中でも特に日本語で説明しておいたほうがよさそうなポイントを纏めている。
本資料を読んだ後に、チュートリアルを両方やってもらったほうがより理解が深まる。

## 関連するQiita記事
[Reactのざっくり概要](https://qiita.com/drafts/82f4d800030f40afda51/edit)
[Reactコンポーネントとは](https://qiita.com/s_harada/items/cb6b3f0d323a40963f8c)

## 参考資料
### ドキュメント
[公式ドキュメント](https://ja.reactjs.org/docs/getting-started.html)

### チュートリアル
[公式チュートリアル](https://ja.reactjs.org/tutorial/tutorial.html)

※余力があれば、以下のチュートリアルも行うことを推奨する
[Getting Started with React - An Overview and Walkthrough Tutorial](https://www.taniarascia.com/getting-started-with-react/)

# Reactコンポーネント間の値の受け渡し
Reactコンポーネント間で値の受け渡しをするには、propsとstateというものを使用する。
[Reactコンポーネントとは](https://qiita.com/s_harada/items/cb6b3f0d323a40963f8c)のSquareコンポーネントとBoardコンポーネントにpropsとstateを加えて説明する。

## propsの追加
propsとは、コンポーネントのプロパティ（引数）のことである。コンポーネントに外から値を引き渡したい場合、propsを使用する。

### コードの例
Squareコンポーネントにpropsを追加すると以下のようなコードになる。

```jsx:board.js
class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {this.props.value}　　//ポイント2
      </button>
    );
  }
}

class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;  //ポイント1
  }

  render() {
    return (
      <div>
        <div className="status">{status}</div>
        <div className="board-row">
          {this.renderSquare(0)}
          {this.renderSquare(1)}
          {this.renderSquare(2)}
        </div>
        <div className="board-row">
          {this.renderSquare(3)}
          {this.renderSquare(4)}
          {this.renderSquare(5)}
        </div>
        <div className="board-row">
          {this.renderSquare(6)}
          {this.renderSquare(7)}
          {this.renderSquare(8)}
        </div>
      </div>
    );
  }
}
```

### 注目すべきポイント
ポイントは以下の2点。

1. BoardコンポーネントのrenderSquare関数でSquareコンポーネントを返す際に、Squareコンポーネントに`value={i}`を渡している
1. Squareコンポーネントは渡されたvalueを`this.props.value`で取り出している

これによって、Squareコンポーネントを描画するときに`value={i}`で0〜9の値が渡されることになり、渡された値はSquareコンポーネントの<button>タグに挟まれる形で`{this.props.value}`の部分で表示されることになる。

### 実行結果
実行結果としては以下のようになる。
（実際にブラウザで表示させたい場合は[React公式チュートリアルのCode Pen](https://codepen.io/gaearon/pen/aWWQOG?editors=0010)で確認）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329353/57eaebd3-715f-2a74-fe84-53eced0a1e3e.png)

## stateの追加
stateとは、コンポーネント内で値を保持するための記憶領域を指す。コンポーネント内で値を保持したい場合にstateを使用する。

### コードの例
Squareコンポーネントにstateを追加すると以下のようなコードになる。

```jsx:board.js
class Square extends React.Component {
  constructor(props) {
    super(props);
    this.state = {  //ポイント1
      value: null,
    };
  }

  render() {
    return (
      <button
        className="square"
        onClick={() => this.setState({value: 'X'})}  //ポイント2
      >
        {this.state.value}
      </button>
    );
  }
}

class Board extends React.Component {
  renderSquare(i) {
    return <Square />;
  }

  render() {
    return (
      <div>
        <div className="status">{status}</div>
        <div className="board-row">
          {this.renderSquare(0)}
          {this.renderSquare(1)}
          {this.renderSquare(2)}
        </div>
        <div className="board-row">
          {this.renderSquare(3)}
          {this.renderSquare(4)}
          {this.renderSquare(5)}
        </div>
        <div className="board-row">
          {this.renderSquare(6)}
          {this.renderSquare(7)}
          {this.renderSquare(8)}
        </div>
      </div>
    );
  }
}
```

### 注目すべきポイント
ポイントは以下の2点。

1. Squareコンポーネントのコンストラクタで、`this.state`に`value: null`を含むオブジェクトを格納している（コード上で明示されていないが、Squareコンポーネントは`this.state`というフィールドを持っている）
1. SquareコンポーネントのボタンがクリックされたときにonClickイベントが発生し、`this.setState({value: 'X'})`が実行される。これによってSquareコンポーネントの`this.state`に`{value: 'X'}`が格納される

### 実行結果
実行結果としては以下のようになる。

（実際にブラウザで表示させたい場合は[React公式チュートリアルのCode Pen](https://codepen.io/gaearon/pen/VbbVLg?editors=0010)で確認）

#### Squareコンポーネントをクリックする前
Squareコンポーネントのstateには、`value: null`が格納されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329353/02401e85-6f30-36dc-4271-d35e8c62cfd9.png)

#### Squareコンポーネントをクリックした後
Squareコンポーネントのstateには、`value: "X"`が格納されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329353/2d08be2d-7472-8a27-1172-4cb3d456c56a.png)