reactjs

React.jsのState

More than 3 years have passed since last update.

昨日はPropについて紹介しましたが、StatePropがImmutableな値であったのに対してMutableな値を定義することが出来ます。


基本的な使い方

基本的にはgetIntialStateでstateの初期値を返して、データに変更があった場合にthis.setStateで更新します。

そうするとComponentがrerenderされて表示が更新されます。子のComponentもrerenderされます。

var Counter = React.createClass({

getInitialState() {
return {
count: 0
};
},
onClick() {
this.setState({ count: this.state.count + 1});
},
render() {
return (
<div>
<span>{this.state.count}</span>
<button onClick={this.onClick}>click</button>
</div>
);
}
});

setStateの第二引数にはsetPropsと同様にcallback関数を指定することが出来ます。

また、setPropsに対してのreplacePropsのようにreplaceStateというstateを置き換える関数もあります。


Stateを使う場面

一番よく使うのがtext fieldのようなComponent内でユーザーのアクションによって変化する値を管理するような場合です。

また、そのComponentが必要とするデータをComponent内でAjaxで取得し反映する場合なども、Ajaxのcallback関数内でresponseをsetStateするように使います。


注意点

stateの値は直接更新してはダメで必ずsetState経由で更新する必要があります。

これはsetStateが呼ばれることでrerenderされるためで、this.stateの値自体もImmutableであると考えておくのがいいとされています。

なので、this.state.listな値があってlistに要素を追加したい時も、pushしてsetStateするのではなくてthis.setState({ list: this.state.list.concat([val]) })として新しい値(配列)にしておいた方がshouldComponentUpdateでチューニングする際にも都合がいいですし、undoの実装なんかもやりやすくなります。


Stateは最低限に

Propだけを持っているようなImmutableなComponentの方が扱いやすいしわかりやすいので、基本的にはPropで考えてStateを持つComponentは最低限にしておくのがよいです。

React.jsでは、rootとなるComponentだけにStateを持たせて後は全部Propだけを持ってるImmutableなComponentにして、何か変更があるとrootのComponentでsetStateしてまとめてrerenderするような構成も可能だったりします。その辺りはVirtualDOMのなせる技なのですが、それはまた別の日に...。


明日はPropやStateを使ってのComponent間のやりとりについて書きたいと思います。