React best way to handle empty object before mount?

javascript, reactjs

Solution

I think you are getting `Can only update a mounted component` error because you are using `componentWillMount` and `settimeout` together, but you dont know if the component 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 `componentDidMount` instead of `componentWillMount` function. That way you can be sure the component is mounted when `componentDidMount` 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 component 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 `componentDidMount` 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.

Problem

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 component 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 component, 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: {} }; }, 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> ); } }) ``` 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?

Original source