Reputation: 241
I am new to ReactJS and trying to understand it. Now I have a situation where I am loading information needed for rendering. But as it is asynchronous the component renders itself before the information is passed to it.
var info;
function getInfo() {
//this will come from backend REST with Backbone which takes a bit
}
var InfoPage = React.createClass({
render: function() {
getInfo()
return (
<div>info: {info}</div>
);
}
});
Now the div will not show the info-value as it is not yet set in the render. So how can I have get render to wait for the info? Or how should this be solved?
The actual React.renderComponent is called from top level and that triggers all the subcomponents so I think I cannot force new render (and I shouldn't?).
Upvotes: 24
Views: 42562
Reputation: 10659
ComponentDidMount
Lifecycle MethodAccording to the docs, componentDidMount
is the component hook you should be using to do your ajax request:
http://facebook.github.io/react/docs/component-specs.html#mounting-componentdidmount
ComponentDidMount
Invoked immediately after rendering occurs... If you want to integrate with other JavaScript frameworks, set timers using setTimeout or setInterval, or send AJAX requests, perform those operations in this method.
Using your example, the code might look like this:
var InfoPage = React.createClass({
getInitialState: function () {
return { info: {} };
},
componentDidMount: function () {
$.ajax({
url: '/info.json',
dataType: 'json',
success: function(data) {
this.setState({info: data});
}.bind(this)
});
},
render: function() {
return (
<div>info: {this.state.info}</div>
);
}
});
getInitialState
Above, we are using the getInitialState
method to return an empty info
object. This allows our component to render, while we wait for the server to return with data.
Once componentDidMount
executes, it will use this.setState
to replace the empty info
and the server data and re-render
the component.
You can see this approach used in in the Updating state section of the React tutorial.
Upvotes: 18
Reputation: 1058
You need to do something like below:
var InfoPage = React.createClass({
getInitialState: function() {
return {info: "loading ... "};
},
componentDidMount: function() {
this.getInfo();
},
render: function() {
return (
<div>info: {this.state.info}</div>
);
},
getInfo:function(){
$.ajax({ url:"restapi/getInfo/whatever", .... }).success(function(res){
this.setState({info:res});
}.bind(this));
}
});
Upvotes: 23