Reactをアカデミックに習う2

# データフローとイベントライフサイクル
# 1. データフローについて
リアクトではデータの流れは常に一方向です。
下記のサンプルでは、
親コンポーネント: RecentChangesTables 
   =>子コンポーネント: Headings
   =>子コンポーネント: Rows
へとPropデータを渡しています。

```js
var RecentChangesTables = React.createClass({
  render: function(){
    return(<table className = 'table'>
             <Headings headings = {this.props.headings} />
             <Rows changeSets = {this.props.changeSets} />
           </table>);
    }
});
```

ajaxと連携する場合には、親コンポーネントのデータstateを使いましょう。

```js
var RecentChangesTables = React.createClass({
	getInitialState: function() {
	    return { data: null };
	},
	componentDidMount: function() {
	    $.get(URL).done(function(data) {
		  this.setState({data: data});
	    }.bind(this));
	},
	render: function() {

	},
});
```

# 2. データ(Props)バリデーション
propTypesを設定する事によってコンポーネントに正しく設定されているか確認できます。
下記はauthorを指定していないサンプルです。
ERRORではなく、コンソールにWARNINGを出力するようになっています。


```js
var App = React.createClass({
  propTypes: {
   headings: React.PropTypes.array,
   changeSets: React.PropTypes.array,
   author: React.PropTypes.string.isRequired
   },
  
  render: function(){
    return(<table className = 'table'>
             <Headings headings = {this.props.headings} />
             <Rows changeSets = {this.props.changeSets} />
           </table>);
    }
});
```

getDefaultPropsにデフォルト値を設定できます。

```js
var App = React.createClass({

 getDefaultProps: function() {
    return {
      headings: ['When happened ', 'Who did it', 'What they change']
    };
  },
  
  render: function(){
            …
  }
});
```

# 3. this.props.childrenについて
this.props.childrenを使って子コンポーネントの描画ができます。

```js
var RecentChangesTable = React.createClass({
  render: function(){
          return(
          <div>
            <h1> Recent Changes </h1>
            <table className='table'>
               {this.props.children}
            </table>
          </div>
          );
  }
});

var App = React.createClass({
  render: function(){
    return(<RecentChangesTable>
             <Headings headings = {this.props.headings} />
             <Rows changeSets = {this.props.changeSets} />
           </RecentChangesTable>);
    }
});
```

# 4. State
Propは親コンポーネントから子コンポーネントに渡される値ですが、Stateはコンポーネントの内部で利用されるものです。Stateの変更はレンダリングに影響します。データが書き換わると更新された部分の再描画がされます。

- 初期化: getInitialStateを利用。
- 更新: setStateを利用。

```js
var App = React.createClass({
  getInitialState: function() {
    return {
      changeSets: []
    };
  },
  handleEvent: function(data) {
    this.setState({ changeSets: data.changeSets });
  },
  render: function(){
    console.log(this.state.changeSets); // prints []  
});
```

# 5. データ更新フロー
Start
 ↓
componentWillMount
 ↓
render
 ↓
componentDidMount
 ↓
shouldComponentUpdate
 ↓
componentWillUpdate
 ↓
render

- componentDidMount
ajaxでデータの取得をします。
HTTPでデータ取得が終わったら、data.map()を利用してデータを作成し、それをsetStateで一旦保存しています。

```
var App = React.createClass({
    getInitialState: function () {
        return {changeSets: [];
    },
    mapOpenLibraryDataToChangeSet: function (data) {
        return data.map(function (change, index) {
            return {
                "when": jQuery.timeago(change.timestamp),
                "who": change.author.key,
                "description": change.comment
            }
        });
    },
    componentDidMount: function () {
        $.ajax({
            url: 'http://openlibrary.org/recentchanges.json?limit=10',
            context: this,
            dataType: 'json',
            type: 'GET'
        }).done(function (data) {
            var changeSets = this.mapOpenLibraryDataToChangeSet(data);
            this.setState({changeSets: changeSets});
        });
    },

    render: function () {
        return (<table className='table'>
            <Headings headings={this.props.headings}/>
            <Rows changeSets={this.state.changeSets}/>
        </table>);
    }
});
```