読者です 読者をやめる 読者になる 読者になる

scramble cadenza

技術ネタのガラクタ置き場

React.js で親子関係にある component の更新順序

javascript

イントロ

話題の React.js を去年末ぐらいから、ちょこちょこと触っています。
殆ど Javascript 触ったこと無い状態から、いきなり React 始めて大分修羅の道だったのですが、最近ようやく慣れてきました。

何となくわかってきた React の性質っぽいものを残しておくメモ

これは何か

React.js で作った component の更新順序を見てみた、というもの。
結論を言ってしまうと、親子関係にあると、必ず 「親 → 子」の順序で更新が行われる

現象

React.js の基本原則として、this.setState を呼ぶと、それがトリガーになって render が呼ばれる、というものがある
(state とは Ruby でいうインスタンス変数のようなもの。setStatesetter だと思えばいい)
以下のように、子も親も同時に setState を呼ぶとどうなるのだろう?という話。

超簡単なサンプルを作ってみた。

var Parent = React.createClass({
  getInitialState: function() {
    return (
      { age: 0 }
    );
  },
  setAge: function() {
    var value = this.refs.age.getDOMNode().value;
    this.setState({ age: Number(value) });
  },
  increment: function() {
    this.setState({ age: this.state.age + 1});
  },
  render: function() {
    console.log('in parent');

    return (
      <div id="parent">
        <h2>parent</h2>
        <p>input parent age: {this.state.age}</p>
        <input type="text" ref="age"/>
        <button onClick={this.setAge}>submit</button>

        <h2>child</h2>
        <Child increment={this.increment} />
      </div>
    );
  }
});

var Child = React.createClass({
  getInitialState: function() {
    return (
      { age: 0 }
    );
  },
  increment: function() {
    this.setState({ age: this.state.age + 1});
    this.props.increment();
  },
  render: function() {
    console.log('in child');
    return (
      <div id="child">
        <p>parent age: {this.state.age}</p>
        <button onClick={this.increment}>a year ago</button>
      </div>
    );
  }
});

React.render(
  <Parent />,
  document.getElementById('parent')
);

最初に親の年齢を入力して、a year ago ボタンを押すと、子供の年齢も親の年齢も 1 インクリメントするやつ。

ところでこのアプリ、親の年齢を入力しないと、親も子も 0 歳からスタートする。0 歳の親ってどういうこっちゃ。
けど細かいところは気にしない。

サンプルの重要なところは React の render で parent から child を作ってるところ。 つまり

- parent
   - child

のような構造を作っている。

一番下の a year ago ボタンをクリックすると、console には

 in parent
 in child

と出力される。
これは先に親の render が呼ばれて、その後に子の render が呼ばれることを意味している。

で、何がいいたい?

どうしてこういう順序になるのか、わからないです。
直感的には setState が先に呼ばれた方、でも良い気もするので。

こういうもの、という理解でいいのだろうか?
「親→子」という流れは理解しやすんだけど、それで無理やり理解した気になるのもなんだかなー。