React.jsのsetStateのタイミングが…

componentWillReceivePropsで親コンポーネントの変化を受け取りAJAXでデータをローディングしようとしたのですがsetStateのタイミングでつまづきました。

親から受け取ったPropsをsetStateしてもrenderされるまでは過去の情報がthis.stateには保存されているらしいです。
[javascript]
var Message = React.createClass({
getInitialState: function () {
return {
date: this.props.date // 親コンポーネントから引き継いだデータ。ここでは仮に「oldDate」とする。
},
componentWillReceiveProps: function (nextProps) {
console.log(this.state.date); // この時点ではgetInitialStateで設定した「oldDate」
this.setState({
date: nextProps.date // 親コンポーネントから受け取った1週間後の「newDate」をセットする。
});
console.log(this.state.date); // この時点で「newDate」が保存されていて欲しいが、実際は「oldDate」
this.loadFromServer(); // 古い日付のデータを取得してしまう。
},
componentDidMount: function () {
this.loadFromServer();
},
loadFromServer: function () {
// this.state.dateを使ってAJAXでデータを取得する。
}
});
[/javascript]

こんな方法が正しいのかわかりませんが、下記のような方法で解決しました。
やはり正しくなかったようです。
[javascript]
var Message = React.createClass({
getInitialState: function () {
return {
date: this.props.date // 親コンポーネントから引き継いだデータ。ここでは仮に「oldDate」とする。
},
componentWillReceiveProps: function (nextProps) {
console.log(this.state.date); // この時点ではgetInitialStateで設定した「oldDate」
this.setState({
date: nextProps.date // 親コンポーネントから受け取った1週間後の「newDate」をセットする。
});
console.log(this.state.date); // この時点で「newDate」が保存されていて欲しいが、実際は「oldDate」
this.loadFromServer(nexProps.date); // しかたがないので、nextPropsのデータを引数として渡す。
},
componentDidMount: function () {
this.loadFromServer(this.state.date);
},
loadFromServer: function (date) {
// 引数dateを使ってAJAXでデータを取得する。
}
});
[/javascript]

コメントでご指摘ただいた事を反映させると
[javascript]
var Message = React.createClass({
getInitialState: function () {
return {
date: this.props.date // 親コンポーネントから引き継いだデータ。ここでは仮に「oldDate」とする。
},
componentWillReceiveProps: function (nextProps) {
console.log(this.state.date); // この時点ではgetInitialStateで設定した「oldDate」
this.setState({
date: nextProps.date // 親コンポーネントから受け取った1週間後の「newDate」をセットする。
});
console.log(this.state.date); // この時点でも「oldDate」
},
componentWillUpdate: function () {
console.log(this.state.date); // この時点で「newDate」
this.loadFromServer(this.state.date); // 変更後のstateを参照できる
},
componentDidMount: function () {
this.loadFromServer(this.state.date);
},
loadFromServer: function (date) {
// 引数dateを使ってAJAXでデータを取得する。
}
});
[/javascript]

スポンサーリンク
レクタングル大




コメント

  1. 匿名 より:

    Reactのコンポーネントライフサイクルでは以下の順にイベントが呼び出されます

    componentWillReceiveProps

    shouldComponentUpdate

    componentWillUpdate

    render

    componentDidUpdate

    この中で、新規に更新したstateを参照することができるのはcomponentWillReceiveProps以降のイベントからとなり、
    今回のケースからすると componentWillUpdate イベントでの参照が適切かと思われます。

    Reactではライフサイクルが重要で、このあたりを理解していないと嵌る可能性があるので一度各イベントを確認するこいとをお勧めします。

  2. Rin より:

    ご指摘ありがとうございます。
    まだReactを触り始めたばかりで理解できていない部分が多いようです。

    React component ライフサイクル図
    http://qiita.com/kawachi/items/092bfc281f88e3a6e456