React.js で親子関係にある component の更新順序
イントロ
話題の React.js
を去年末ぐらいから、ちょこちょこと触っています。
殆ど Javascript
触ったこと無い状態から、いきなり React
始めて大分修羅の道だったのですが、最近ようやく慣れてきました。
何となくわかってきた React の性質っぽいものを残しておくメモ
これは何か
React.js
で作った component の更新順序を見てみた、というもの。
結論を言ってしまうと、親子関係にあると、必ず 「親 → 子」の順序で更新が行われる
現象
React.js
の基本原則として、this.setState
を呼ぶと、それがトリガーになって render
が呼ばれる、というものがある
(state
とは Ruby でいうインスタンス変数のようなもの。setState
は setter
だと思えばいい)
以下のように、子も親も同時に 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
が先に呼ばれた方、でも良い気もするので。
こういうもの、という理解でいいのだろうか?
「親→子」という流れは理解しやすんだけど、それで無理やり理解した気になるのもなんだかなー。