reactjsの子コンポーネントのgetInitialStateおよびComponentDidMountのpropsデータオブジェクトを読み取ることができません

ユーザー1230321

これが私が試した小さなコードです:

var CommentBox = React.createClass({
        loadCommentsFromServer: function () {
            $.ajax({
                url: this.props.url,
                dataType: 'json',
                type: 'GET',
                success: function (data) {
                    this.setState({data: data});
                }.bind(this),
                error: function (xhr, status, err) {
                    console.error(this.props.url, status, err.toString());
                }.bind(this),
                cache: false
            });
        },
        getInitialState: function () {
            return {data: []};
        },
        componentDidMount: function () {
            this.loadCommentsFromServer();
        },
        render: function () {
            return (
                    <div className="commentBox">
                        <MessageBox1 data={this.state.data}/>
                    </div>
            );
        }
    });

    var MessageBox1 = React.createClass({
        getInitialState: function() {
            alert('MessageBox1 getInitialState');
            return {nameWithQualifier: 'Mr. ' + this.props.data.pageName};
        },
        componentDidMount: function() {
            alert('this.props.data: ' + this.props.data);
        },
        render: function() {
            return (<div>
                        <div>{this.state.nameWithQualifier}</div>
                        <div> {this.props.data.pageName}</div>
                    </div>
            );
        }
    });

ReactDOM.render(<CommentBox url="/save/6"/>, document.getElementById('content'));

CommentBoxで、ID 6のオブジェクトをクエリし、MessageBox1コンポーネントに渡します。このオブジェクトをMessageBox1コンポーネントの状態変数にしたい。ここでの問題は、props変数を読み取ることができないことです。「this.props.data」は、MessageBox1コンポーネントのgetInitialStateおよびComponentDidMountで定義されていません。一方、レンダリング関数では正しい値を確認できます。getInitialStateで小道具データを読み取ることができるいくつかの例を試しました。なぜこれがここで起こらないのですか?助けてください。コンソールにエラーはありません。

jmancherje

反応コンポーネントのライフサイクルに混乱が生じていると思います。

この記事をすばやく読んで、各ライフサイクルメソッドがいつ呼び出されるかを理解することをお勧めします。http://busypeoples.github.io/post/react-component-lifecycle/

getInitialStateメソッドのmessagebox1で、このように状態構造を初期化して、小道具が使用可能になる前に小道具にアクセスできないようにします。

{ nameWithQualifier: '' }

非同期アクションを呼び出してデータをフェッチしているため、データがいつ取得されるかは保証されません。ただし、(componentDidMountでの)現在の状態に基づいて、messageBox1が初期化された後に常に取得されます。これは、this.props.dataがgetInitialStateで未定義である理由を説明しています。componentWillMountでloadCommentsFromServerをトリガーして、非同期アクションをできるだけ早くトリガーすることをお勧めします。コンポーネントがマウントされる前にsetStateを設定することもできます。

setInitialStateでmessageBox1の状態を設定する代わりに、次のようにcomponentWillReceivePropsを使用してみてください。小道具が変更されたときに状態が更新されることが保証されます。

componentWillReceiveProps(newProps) {
    this.setState({ nameWithQualifier: 'Mr. ' + newProps.data.pageName })
}

ただし、このネストされたmessageBox1コンポーネントがレンダリングされる前に、偶然に非同期データが使用可能になった場合は、messageBox1でこれを実行して、最初のレンダリングで状態が最新であることを確認することもできます。

componentWillMount() {
    this.setState({ nameWithQualifier: 'Mr. ' + this.props.data.pageName })
}

したがって、本当にこれを実行したい場合は、上記の2つの提案をお勧めします

  1. componentWillMountでajaxリクエストを呼び出して、リクエストを先に送信します
  2. componentWillReceivePropsの子コンポーネントの状態を更新します(小道具が更新されるたびに状態が更新されます)

ただし、ほとんどの場合、小道具を使用してコンポーネントの状態を設定する必要はないようです。多分このようなことを試してみてください:

commentBoxコンポーネントのrender関数で、pageNameを小道具として送信します。

   render: function () {
        return (
                <div className="commentBox">
                    <MessageBox1 pageName={this.state.data.pageName}/>
                </div>
        );
    }

また、messageBoxレンダリング関数では、小道具に直接アクセスすることでプロセスを簡素化できます。それはあなたに同じ結果を与えるでしょう。

    render: function() {
        return (<div>
                    <div>{'Mr. ' + this.props.pageName}</div>
                    <div> {this.props.pageName}</div>
                </div>
        );
    }

これは、何らかの理由でmessageBox1内の小道具を変更する必要がない限り、この単純なケースで機能します。小道具は、それらが存在するコンポーネントによって不変であるためです。親コンポーネントが渡されたものを変更した場合にのみ更新されます。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ