React


データフロー


Reactのデータフロー:親→子

コンポーネントの仕事:親から受け取ったプロパティを描画すること

ツリーの最上位のコンポーネントでプロパティが変更されると、 その変更を下位のプロパティへ伝えることでツリー全体へ伝播させることで そのプロパティを参照するすべてのコンポーネントは再描画される

Reactコンポーネントは、propsとstateを受け取り仮想DOMを出力する一種の関数とみなせる

4.1 props

propsはプロパティのこと

コンポーネントはを作成するときに属性値として指定した値がコンポーネントのプロパティとなる

var surveys = [{title:'Superheroes'}];
<Listsurveys surveys={surveys} />
レアケースとして setProps を使って指定することも可能
var surveys = [{title:'Superheroes'}];
var listSurveys = React.render(
  <ListSurveys />,
  document.queryselector('body')
);
listSurveys.setProps({surveys:surveys});

setProps は必ず子コンポーネントに対して呼び出すか、  上記のようにコンポーネントツリーの外側で呼び出す。

this.setPropsのように自分自身に対して呼び出したり、 this.propsを直接変更してはならない。この場合はstateを使う

プロパティを文字列で指定

<a href='/surveys/add'>サーベイを追加</a>
プロパティを{}で指定
<a href='/surveys/'+survey.id>{survey.title}</a>
オブジェクトをそのまま一組のプロパティとして指定
var ListSurveys = React.createClass({
  render: function(){
    var proprs = {
      one:'foo',
      two:'bar'
    };
    return &ltSurveyTable {...props} />;
  }
});
プロパティはイベントハンドラを格納するためにも使用される
var SaveButton = React.createClass({
  render: function(){
    return (
      <a className='button save' onClick={this.handleClick}>保存</a>
    );
  },
  handleClick: function(){
    // ...
  }
});

4.1.1 propTypes

プロパティとして渡された値のバリデーションを行う手段を提供する

var SurveryTableRow = React.createClass({
  propTypes: {
    survey: React.PropTypes.shape({
      id: React.PropTypes.number.isRequired
    }).isRequired,
    onClick: React.PropTypes.func
  },
  // ...
}); 
コンポーネント作成時に渡されたプロパティが、propTypesで指定された条件を満たさない場合 console.warnで警告を出力してくれる

propTypesは省略可能ですが、コンポーネントの仕様を明確に宣言できるので積極的に利用すべき

4.1.2 getDefaultProps

プロパティの初期値を定義する

ここで定義した初期値は、コンポーネント作成時にプロパティが指定されなかった場合に使用される

propTypesで isRequired の指定が無い場合にのみ定義できる

var SurveyTable = React.createClass({
  getDefaultProps: function(){
    return {
      surveys:[]
    };
  }
  // ...
});

getDefaultPropsで返される値は、createClassが呼び出されたときにキャッシュされ コンポーネントのインスタンスが作成されたときにその値を共有し利用するので、 インスタンスごとに別々の値を指定することはできない

4.2 state

コンポーネントの内部状態で、コンポーネント内部でのみ使用される

一般的に要素の表示内容を決定する場合に使用される

var CountryDropdown = React.createClass({
  getInitialState: function(){
    return {
      showOptions: false
    };
  },
  render: function(){
    var options;
    if (this.state.showOptions) {
      options = <coutryoptions></coutryoptions>
    }
    return (
      <div className='dropdown' onClick={this.handleClick}>
        <label>国を選択してください</label>
        {option}
      </div>
    );
  },
  handleClick: function(){
    this.setState({showOptions: true});
  }
});

getInitialStateで初期化

setStateで更新

render が呼び出される

出力に変更があると仮想DOMが更新

実際のDOMが更新される

4.3 state と props の使い分け

state には コンポーネントの機能として必要な単純なデータを保持するため

propsの値をstateにコピーすることは避けるべきで、単一の情報源としてりようすべき

ただし、propsの値をstateの初期値に利用することは可能