Reagieren state variable unerwartet undefined, wenn Sie versuchen zu gehen, wie Requisiten

Ich habe einen Reagieren Hierarchie wie diese:

 AgreementContentWidget
   AgreementTitleContainer
     AgreementTitle <-- this is ok, but
     CommentList    <-- problem here
   SectionsContainer

Montage AgreementContentWidget:

 <AgreementContentWidget agreement_id={85} />

Anforderungen der widget geladen Vereinbarung 85.

var AgreementContentWidget = React.createClass({
  getInitialState: function() {
    return {agreement: []};
  },

  componentWillMount: function() {
    this.loadAgreementDetails();
  },

  loadAgreementDetails: function() {
    $.ajax({
      url: "/agreements/" + this.props.agreement_id, 
      type: 'GET',
      dataType: 'json',
      success: function(agreement) {
        this.setState({agreement: agreement.agreement});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error("/agreements/" + this.props.agreement_id, status, err.toString());
      }.bind(this)
    });
  },

  handleAgreementUpdate: function() {
    this.loadAgreementDetails();
  },

  render: function() {
    return (
      <div className="panel panel-default">
        <div className="panel-body" id={"container_agreement_" + this.state.agreement.id}>
          <div className="col-lg-12">           
            <AgreementTitleContainer agreement={this.state.agreement} onAgreementUpdate={this.handleAgreementUpdate} />
            <SectionsContainer agreement={this.state.agreement} />
          </div>
        </div>
      </div>
    );
  }
});

Ich pass agreement={this.state.agreement} zu <AgreementTitleContainer> zu erbringen Komponenten, aus denen eine Vereinbarung Titel.

Innen <AgreementTitleContainer>:

var AgreementTitleContainer = React.createClass({
  handleAgreementUpdate: function() {
    this.props.onAgreementUpdate();
  },

  render: function() {
    return (
      <div className="row" id="container_title">
        <AgreementTitle agreement={this.props.agreement} onAgreementUpdate={this.handleAgreementUpdate} />
        <CommentList commentable_type={"agreement"} commentable_id={this.props.agreement.id} />
        <br />
      </div>
    );
  }
});

<AgreementTitle> nimmt {this.props.agreement} und es hat den Inhalt der Vereinbarung, 85. Es macht und tut andere Operationen, wie erwartet. Jedoch <CommentList> hat undefined für commentable_id als this.props.agreement.id undefined (per debugger: this.props.agreement ist immer undefiniert für diese Komponente).

Also:

  • Warum ist {this.props.agreement} definiert <AgreementTitle>?
  • Warum ist es undefiniert, für <CommentList>?

Ich weiß, dass <CommentList> wie erwartet funktioniert in anderen Kontexten, in denen ein Wert übergeben wird, um commentable_id (z.B. commentable_id={42}) anstatt von einem Objekt in this.state (wie oben).

Stellte ich fest, dass für <CommentList> wenn er versucht eine GET Anfrage in loadComments() unten:

var CommentList = React.createClass({
  getInitialState: function() {
    return {comments: []};
  },

  componentDidMount: function() {
    this.loadComments();
  },

  loadComments: function() {
    $.ajax({
      url: "/comments/?commentable_type=" + this.props.commentable_type + "&id=" + this.props.commentable_id, 
      type: 'GET',
      dataType: 'json',
      success: function(comments) {
        this.setState({comments: comments.comments});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error("/comments/?commentable_type=" + this.props.commentable_type + "&id=" + this.props.commentable_id, status, err.toString());
      }.bind(this)
    });
  },
  ...
  ...
}

Bekomme ich eine Fehlermeldung von ausgefallenen GET

GET https://tinya-thedanielmay-2.c9.io/comments/?commentable_type=agreement&id=undefined 404 Not Found

was ich erwarte, wie id (aus this.props.commentable_id oben) ist undefined. Jedoch, die console.error Funktion dann druckt:

/comments/?commentable_type=agreement&id=85 error Not Found

Also an diesem Punkt der Ausführung, this.props.commentable_id scheint nun definiert.

Ich denke, dass die Entscheidung für <AgreementContentWidget> zu:

  • GET Vereinbarung 85
  • Set this.state.agreement mit Zustimmung 85 details <--
  • Dann weiter verwenden this.state.agreement als Eingabe für Requisiten, z.B. agreement={this.state.agreement}

hat etwas zu tun mit meinen Fragen.

Architektonisch, würde ich gerne behalten, die GET Vereinbarung <AgreementContentWidget> Ebene und haben das abgerufen Vereinbarung details, propagate down.

Was bin ich?

  • Ich glaube nicht, dass dies irgendetwas damit zu tun hat mit deinem problem aber Reagieren die docs sagen, speziell zum laden von ajax in ComponentDidMount wie du tust in CommentList. In AgreementWidget, die Sie laden, ajax in ComponentWillMount.
InformationsquelleAutor Daniel May | 2015-06-04
Schreibe einen Kommentar