当试图作为道具传递时,React状态变量意外未定义
React state variable unexpectedly undefined when trying to pass as props
我有一个这样的React组件层次结构:
AgreementContentWidget
AgreementTitleContainer
AgreementTitle <-- this is ok, but
CommentList <-- problem here
SectionsContainer
mount AgreementContentWidget
:
<AgreementContentWidget agreement_id={85} />
请求小部件加载协议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>
);
}
});
我将agreement={this.state.agreement}
传递给<AgreementTitleContainer>
以呈现包含协议标题的组件。
Inside <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>
取{this.props.agreement}
,其内容为协议85。它按预期呈现并执行其他操作。然而,<CommentList>
对commentable_id
有undefined
,因为this.props.agreement.id
是未定义的(通过调试器:this.props.agreement
对于该组件总是未定义的)。
:
- 为什么
{this.props.agreement}
定义为<AgreementTitle>
? - 为什么
<CommentList>
没有定义?
我知道<CommentList>
在其他上下文中按预期工作,其中值传递给commentable_id
(例如commentable_id={42}
)而不是从this.state
中的对象(如上所述)。
我注意到,对于<CommentList>
,当它在loadComments()
中尝试GET
请求时:
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)
});
},
...
...
}
我从失败的GET
得到一个错误消息
GET https://tinya-thedanielmay-2.c9.io/comments/?commentable_type=agreement&id=undefined 404 Not Found
我期望,因为id
(从上面的this.props.commentable_id
)是undefined
。然而,console.error
函数随后打印出:
/comments/?commentable_type=agreement&id=85 error Not Found
在执行时,this.props.commentable_id
似乎已经被定义了。
我认为<AgreementContentWidget>
的决定:
-
GET
协议85 - 设置
this.state.agreement
与85协议细节<—— - 然后继续使用
this.state.agreement
作为道具的输入,例如agreement={this.state.agreement}
和我的问题有关。
在体系结构上,我希望将GET
协议保留在<AgreementContentWidget>
级别,并将检索到的协议细节向下传播。
我错过了什么?
你在getInitialState
中初始化的是<AgreementContentWidget>
第一次渲染时传递的内容。您认为<AgreementTitle>
工作正常,因为当您从后端获得协议数据时,它会重新渲染,但是CommentsList依赖于该ID来加载自己的数据,在渲染之前会出错。它不知道要出去再次获取数据,因为它只在componentDidMount
中加载。
您应该延迟检索注释,直到获得正确的属性。要做到这一点,使用React的componentWillReceiveProps(nextProps)
函数,直到agreement.id
存在,并且在加载ajax之前不为0。
所以从CommentList中删除this.componentDidMount
并添加这个:
this.componentWillReceiveProps(nextProps){
if(nextProps.agreement && nextProps.agreement.id){
this.loadComments();
}
}
您还应该设置propTypes,以便您可以通过良好的消息提醒这些问题,并为您的代码提供一些自我文档。
- React redux初始化功能,无论状态变化如何
- 未捕获的类型错误:无法读取属性'状态'在react中为null
- React js更改状态不会更新组件
- React-状态未更新
- 如何在渲染函数中检查 react 中子组件的状态
- 复选框保持React JS中各组件的状态
- React Container-来自任一reducer的访问状态
- 获取已从日期选择器中选择的输入的 React 状态
- React状态嵌套属性
- 使用继电器更新React状态
- 如何将React状态绑定到RxJS可观察流
- ReactFire-获取'对象作为React子对象无效'将Firebase绑定到React状态时
- 使用debounce将React状态同步到Meteor集合
- 使用不变性助手更新React状态下的数组对象
- 改变来自React状态的字符串
- 为什么我不能在Tracker.Autorun中访问React状态?
- React状态改变不是渲染
- React状态的改变不会导致组件重新渲染
- 从子元素到父元素的React状态绑定
- 当试图作为道具传递时,React状态变量意外未定义