1. koba04

    Posted

    koba04
Changes in title
+React.jsのComponentについて
Changes in tags
+React
v0.12.1
Changes in body
Source | HTML | Preview
@@ -0,0 +1,138 @@
+今回はComponentについて書いていきたいと思います。
+
+React.jsでは基本的にはComponentを作って組み合わせていくことでアプリケーションを作っていきます。
+
+## render
+
+Componentは`React.createClass`に`render`メソッドをもったオブジェクトを渡すことで作成することが出来ます。
+
+```js
+var Hello = React.createClass({
+ render() {
+ return (
+ <div><span>hello</span></div>
+ )
+ }
+})
+```
+
+その際、`render`メソッドはComponentを1つ返す必要があります。
+
+↓のように複数のComponentを返すことは出来ません。
+
+```js
+ // ダメ
+ render() {
+ return (
+ <div>title</div>
+ <div>contents</div>
+ )
+ }
+
+ // OK
+ render() {
+ return (
+ <div>
+ <div>title</div>
+ </div>contents</div>
+ </div>
+ )
+ }
+```
+
+また、renderメソッドはどのタイミングで何度呼ばれるかわからないので必ず冪等性がある実装にする必要があります。
+
+## Separation of concerns?
+
+ところで、React.jsではComponentとして、マークアップとViewのロジックをcreateClassの中に書いていくのですが、他のフレームワークのようにマークアップはHTMLやmustacheで書いてViewのロジックをJSで書くみたいに分かれてなくて気持ち悪い!という人もいるのではないでしょうか?
+
+それに対して、React.jsの開発者であるPete Huntはそれは「関心の分離(Separation of concerns)」ではなくて「技術の分離(Separation of technologies)」だとしていて、マークアップとViewのロジックは密であるべきとしています。
+
+それにTemplateのSyntaxで不自由にコードを書くよりJavaScriptで書いた方がいいとしています。
+
+テストが...という問題は、React.jsではTestUtilsというAddonでサポートしています。
+
+
+## Component間のやりとり
+
+PropをI/Fとして外部とやりとりすることが出来ます。
+
+`<Hello name="foo" />`のようにすると、`this.props.name`として参照することが出来ます。
+
+```js
+var Hello = React.createClass({
+ render() {
+ return (
+ <div>Hello {this.props.name}</div>
+ )
+ }
+});
+
+// <Hello name="React" />
+// <div>Hello React</div>
+```
+
+Propについては明日に書く予定です。
+
+
+## 動的に更新する
+
+ユーザーのアクションやAjaxリクエストなどにより、動的に値が変化するような場合はStateを使います。
+
+`this.state.xxx`で参照して、更新するときは`this.state`を更新するのではなくて必ず`this.setState`を使用する必要があります。
+
+```js
+var Counter = React.createClass({
+ getInitialState() {
+ return {
+ count: 0
+ };
+ },
+ onClick() {
+ this.setState({count: this.state.count + 1});
+ },
+ render() {
+ return (
+ <div>
+ <div>count:{this.state.count}</div>
+ <button onClick={this.onClick}>click!</button>
+ </div>
+ );
+
+ }
+});
+```
+
+Stateについては明後日に書く予定です。
+
+
+## React.createClassについて
+
+Componentを作成にするときに使う関数ですが、v0.11からv0.12にかけて挙動が変わりました。
+以前は、Componentの定義を作りつつComponentのElementを返しているという2つのことをやっていたのですが、v0.12からはそれが分離されてComponentの定義を作成して返すだけになりました。
+
+つまりElementではないので、使うときには`React.createElement(Component, {name: 'xxx'})`のようにReact Elementにしてあげる必要があります。ちなみに`React.createFactory(Component)`とやることも出来ます。
+
+ただJSXを使っている場合は、これまでと同じように`React.createClass`の戻り値を`<Component />`のように直接渡しても大丈夫です。
+
+```js
+var Hello = React.createClass({
+ render() {
+ return <div>{this.props.name}</div>;
+ }
+});
+
+React.render(React.createElement(Hello, {name: "foo"}), document.body);
+// or
+React.render(React.createFactory(Hello)({name: "foo"}), document.body);
+// JSXはそのままでOK
+React.render(<Hello name="foo" />, document.body);
+```
+
+この変更には今までがcreateClassという名前以上のことをやっていたというのもあるのですが、createElementを通してComponentを作成するようにすることで最適化の余地を与えたり、将来的に`React.createClass`を使っているところをES6のclassで定義出来るようにするという意図もあったりします。
+
+--------
+
+Componentについてはそのほかにも、Lifecycleに応じたhookがあったりするのですが、その辺りについても今後紹介していきたいと思います。
+
+明日は`Prop`について書きたいと思います。