I have a React component that displays information about an entity. The id of the entity is passed in via a property. The component starts an AJAX call in "componentDidMount" to fetch the entity and updates state when the call completes/fails.
This works fine except that the component does not fetch new data when the entity id changes (via props).
I have tried starting a call in "componentWillReceiveProps" but at that stage the component still has is old properties set. I would have to pass nextProps to the AJAX call method and that doesn't seem right.
What is the best/cleanest way to have a component asynchronously update its state in response to a property change?
Where in the component lifecycle should I make an AJAX call? You should populate data with AJAX calls in the componentDidMount lifecycle method. This is so you can use setState to update your component when the data is retrieved.
To update our state, we use this. setState() and pass in an object. This object will get merged with the current state.
React will then look at the virtual DOM, it also has a copy of the old virtual DOM, that is why we shouldn't update the state directly, so we can have two different object references in memory, we have the old virtual DOM as well as the new virtual DOM.
setState() enqueues changes to the component state and tells React that this component and its children need to be re-rendered with the updated state. This is the primary method you use to update the user interface in response to event handlers and server responses.
I'm new to react as well, so the Flux architecture is a bit intimidating to me. I'm doing it exactly as you said, using componentWillMount
to load initial data via AJAX, and then componentWillReceiveProps
with nextProps
to load new data again if/when props change:
var Table = React.createClass({
getInitialState: function() {
return { data: [] };
},
componentWillMount: function(){
this.dataSource();
},
componentWillReceiveProps: function(nextProps){
this.dataSource(nextProps);
},
dataSource: function(props){
props = props || this.props;
return $.ajax({
type: "get",
dataType: 'json',
url: '/products?page=' + props.page + "&pageSize=" + props.pageSize
}).done(function(result){
this.setState({ data: result });
}.bind(this));
},
render: function() {
return (
<table className="table table-striped table-bordered">
<Head />
<Body data={this.state.data}/>
</table>
);
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With