Reputation: 246
I have a parent class and a child class. The child class will perform an initial load operation based on a property passed from the parent. The parent class will access that data using a static method from the child. In essence, I'm trying to use the child class as a service. The code below illustrates the scenario (note that it's just pseudo code).
var Parent = React.createClass({
componentDidMount: function() {
console.log("parent component was mounted");
},
render: function() {
return (
<div>
<Child param={this.props.param} />
<p>Child.fetch('key')</p>
</div>
);
}
});
var Child = React.createClass({
getInitialState: function() {
return {
data: {}
};
},
componentDidMount: function() {
console.log("child component was mounted");
$.ajax({
url: "server/api.php",
data: {
param: param
}
}).done(function(response) {
this.setState({data: response});
}.bind(this));
},
statics: {
get: function(key) {
console.log('get requested for key: ' + key);
var value = null; // default value
if(this.data == null) { return value; }
//get the value from the data based on the key
return value;
}
},
render: function() {
return (
<h2>{this.props.param}</h2>
);
}
});
The problem here is that the parent's render function does not update after the data was loaded from the child class. The order of the console.log results is:
I'm not sure if its possible to trigger the parent's render function only once after the child component has been loaded. I'm guessing its not, so triggering an update for the parent's render method would suffice. Any suggestions, improvements are welcome as this is fairly new to me.
Upvotes: 1
Views: 3964
Reputation: 2844
You should add a callback prop to your Child
component that the child can trigger once the data has been loaded.
On the Parent
side you just need to call this.forceUpdate()
.
What you are experiencing is expected since the lifecycle of your Child
component is different than the one for your Parent
class.
Still, you might need to analyze the possibility to move your load logic into the Parent
and delegate the rendering of parts of the response to each child. This will also help performance since only one HTTP request will be needed to load all the data.
** Code **
var Parent = React.createClass({
componentDidMount: function() {
console.log("parent component was mounted");
},
render: function() {
return (
<div>
<Child param={this.props.param} onDataLoaded={this.forceUpdate} />
<p>Child.fetch('key')</p>
</div>
);
}
});
var Child = React.createClass({
getInitialState: function() {
return {
data: {}
};
},
componentDidMount: function() {
console.log("child component was mounted");
$.ajax({
url: "server/api.php",
data: {
param: param
}
}).done(function(response) {
if (typeof this.onDataLoaded === 'function')
this.onDataLoaded();
this.setState({data: response});
}.bind(this));
},
statics: {
get: function(key) {
console.log('get requested for key: ' + key);
var value = null; // default value
if(this.data == null) { return value; }
//get the value from the data based on the key
return value;
}
},
render: function() {
return (
<h2>{this.props.param}</h2>
);
}
});
Upvotes: 1