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


この記事の目的

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

関連するQiita記事

Reactのざっくり概要
Reactコンポーネントとは

参考資料

ドキュメント

公式ドキュメント

チュートリアル

公式チュートリアル

※余力があれば、以下のチュートリアルも行うことを推奨する
Getting Started with React - An Overview and Walkthrough Tutorial

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

Reactコンポーネント間で値の受け渡しをするには、propsとstateというものを使用する。
ReactコンポーネントとはのSquareコンポーネントとBoardコンポーネントにpropsとstateを加えて説明する。

propsの追加

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

コードの例

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

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}を渡している
  2. Squareコンポーネントは渡されたvalueをthis.props.valueで取り出している

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

実行結果

実行結果としては以下のようになる。
(実際にブラウザで表示させたい場合はReact公式チュートリアルのCode Penで確認)

stateの追加

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

コードの例

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

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

実行結果

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

(実際にブラウザで表示させたい場合はReact公式チュートリアルのCode Penで確認)

Squareコンポーネントをクリックする前

Squareコンポーネントのstateには、value: nullが格納されている。

Squareコンポーネントをクリックした後

Squareコンポーネントのstateには、value: "X"が格納されている。