我有一个React类,它想要渲染一个如下所示的对象:
data: {
title: "haha",
description: {
country: "US",
year: "1996"
}
}
但是,当React想要呈现它时,它会产生错误。
未捕获错误:不变违规:receiveComponent(...):只能更新已安装的组件
我认为问题出在 getInititalState 中,我将数据声明为空对象,所以当我在超时后获取完整数据对象时,React会尝试将我的数据对象映射到组件,但它给出了错误。
但有一件有趣的事情是,我访问 this.props.title.title 没有问题,但是没有 this.props.title.description.country ,它会给出未定义的
但是,当我调试它时,我可以看到我的对象。但是React无法访问它!
我的猜测是当React从空对象初始化时,它只会使用数据对象的第1级和第2级初始化虚拟DOM。
当我尝试访问 this.props.data.data.title 时,原因是正常但不是 this.props.data.data.description.country
以下是我的代码
var BookBox = React.createClass({
getInitialState: function() {
return { data: {} };
},
componentWillMount: function() {
var that = this;
setTimeout(function() {
console.log('timeout');
that.setState({
data: {
title: "haha",
description: {
country: "US",
year: "1996"
}
}
});
}, 2000);
},
render: function() {
return (
<div>
<h1>{this.state.data.title}</h1>
<TestBox title={this.state.data} />
</div>
);
}
});
var TestBox = React.createClass({
render: function() {
console.log(this.props.title);
return (
<div>
<p>{ this.props.title.description.country }</p>
<p>{ this.props.title.title }</p>
</div>
);
}
})
我可以知道处理这个问题的最佳方法是什么?我应该在 getInitialState 中初始化我的数据对象结构还是有更好的方法?
答案 0 :(得分:4)
我认为您收到Can only update a mounted component
错误,因为您一起使用componentWillMount
和settimeout
,但您不知道该组件是否已在时间settimeout
功能下装入火灾。
由于您事先知道自己的状态,我认为最好从getInitialState
函数返回您的数据。
您也可以使用componentDidMount
代替componentWillMount
功能。这样,您可以确保在调用componentDidMount
时安装组件。
任何时候使用as settimeout
或xhr调用等asycn函数时,都应该在回调函数中使用this.isMounted()
,以便在回调触发时检查组件是否仍然挂载。
例如,如果您事先未了解状态,则可以在componentDidMount
函数中触发xhr调用,在成功回调中检查this.isMounted()
并setState
。
至于<p>{ this.props.title.description.country }</p>
行的错误:初始渲染时this.state.data
(BookBox)是一个空对象,因此是this.props.title
(TestBox)。访问空对象({ }
)title
属性为undefined
。没问题。访问description
也是undefined
。但访问undefined
的{{1}}是错误的。为避免此错误,您可以创建country
变量:description
并使用description = this.props.title.description || {}
确保在<p>{description.country}</p>
为空时代码不会中断。