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 inComponentWillMount
.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Was Sie initialisieren im
getInitialState
ist, was übergeben wird das erste mal<AgreementContentWidget>
macht. Sie denken<AgreementTitle>
funktioniert, weil es neu gerendert, wenn Sie die Vereinbarung Daten aus dem backend, aber CommentsList, abhängig zu sein, die ID zu laden Ihre eigenen Daten, wird ein Fehler ausgegeben, bevor es machen kann. Es weiß nicht, zu gehen und sich die Daten noch einmal, weil es nur vom laden incomponentDidMount
.Sollten Sie stellen Sie den Abruf der Kommentare, bis man die richtige Eigenschaft. Um dies zu tun, verwenden Sie Reagieren, ist
componentWillReceiveProps(nextProps)
Funktion und warten Sie, bisagreement.id
existiert und nicht 0 ist, bevor das laden der ajax.So ENTFERNEN
this.componentDidMount
aus CommentList und FÜGEN Sie diese:Muss man auch propTypes damit du gewarnt werden kannst, um diese Probleme mit nette Nachrichten und bieten einige self-Dokumentation zum code.
this.state.agreement
mit einem temporären Objekt (z.B.id == 0
) keine Lösung für das grundlegende problem: statt<CommentList>
laden mit undefinierten Objekt, es versucht zu laden, die mit temporären Objekt-id. Ich verstehe nicht, wie kann ich passthis.state.agreement
in eine Komponente, geladen nach der Montage ... haben zwei untergeordnete Komponenten verwenden Sie es als Stütze, aber eine Kind-Komponente verhält sich wie erwartet mit Daten geladen, aber das andere Kind Komponente nicht (es verwendet initialisiert Daten). 🙂<AgreementTitle>
laden nicht ajax, sondern rendert (ich weggelassen, um zu versuchen, um es kurz zu machen). Ich geändert wie pro Ihren Vorschlag und dieser bekommt die Kommentare laden - Juhu. Noch die Lösung einige zusätzliche Variablen undefiniert, aber bin arbeiten durch einige Ihrer Vorschläge. Wird aktualisiert und die Flagge etwas, dass ich fest auf.