I have a React class, and it wants to render an object shown below:
data: {
title: "haha",
description: {
country: "US",
year: "1996"
}
}
But, when React wants to render it, it gives an error.
Uncaught Error: Invariant Violation: receiveComponent(...): Can only update a mounted ponent
I think the problem is in the getInititalState, I declare my data as an empty object, so when I get my full data object after the timeout, React will try to map my data object to the ponent, but it gives error.
But one interesting thing is, I have no problem accesing this.props.title.title, but not this.props.title.description.country, it will give undefined
But, when I console.log it, I could see my object. But React cant access it!
My guessing is when React initializing from the empty object, it will only init the virtual DOM with the 1st and 2nd level of the data object.
That the reason, when I try to access this.props.data.data.title is OK but not this.props.data.data.description.country
Below is my code
var BookBox = React.createClass({
getInitialState: function() {
return { data: {} };
},
ponentWillMount: 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>
);
}
})
May I know what is the best way to handle this problem? should i init my data object structure in the getInitialState or there is a better way?
I have a React class, and it wants to render an object shown below:
data: {
title: "haha",
description: {
country: "US",
year: "1996"
}
}
But, when React wants to render it, it gives an error.
Uncaught Error: Invariant Violation: receiveComponent(...): Can only update a mounted ponent
I think the problem is in the getInititalState, I declare my data as an empty object, so when I get my full data object after the timeout, React will try to map my data object to the ponent, but it gives error.
But one interesting thing is, I have no problem accesing this.props.title.title, but not this.props.title.description.country, it will give undefined
But, when I console.log it, I could see my object. But React cant access it!
My guessing is when React initializing from the empty object, it will only init the virtual DOM with the 1st and 2nd level of the data object.
That the reason, when I try to access this.props.data.data.title is OK but not this.props.data.data.description.country
Below is my code
var BookBox = React.createClass({
getInitialState: function() {
return { data: {} };
},
ponentWillMount: 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>
);
}
})
May I know what is the best way to handle this problem? should i init my data object structure in the getInitialState or there is a better way?
Share Improve this question edited Feb 20, 2015 at 9:16 nilgun 10.6k4 gold badges48 silver badges57 bronze badges asked Feb 20, 2015 at 8:43 TimTim 3,8033 gold badges37 silver badges57 bronze badges1 Answer
Reset to default 4I think you are getting Can only update a mounted ponent
error because you are using ponentWillMount
and settimeout
together, but you dont know if the ponent has been mounted by the time settimeout
function fires.
Since you know what your state is beforehand, I think it is best to return your data from getInitialState
function.
You can also use ponentDidMount
instead of ponentWillMount
function. That way you can be sure the ponent is mounted when ponentDidMount
is called.
Any time time you are using asycn functions like settimeout
or a xhr call, you should use this.isMounted()
in the callback function, to check that the ponent is still mounted by the time the callback fires.
For example, if you didnt know the state beforehand, you could fire an xhr call in the ponentDidMount
function, check this.isMounted()
in the success callback and setState
.
As for the error on <p>{ this.props.title.description.country }</p>
line: At initial render this.state.data
(BookBox) is an empty object so is this.props.title
(TestBox). Accessing empty object's ({ }
) title
property is undefined
. No problem there. Accessing description
is also undefined
. But accessing undefined
's country
is error. To avoid this error you can create a description
variable: description = this.props.title.description || {}
and use <p>{description.country}</p>
to make sure your code doesnt break if this.props.title
is empty.