Reputation: 3844
I am relatively new(ish) to React so still trying to learn best practice etc..
I am currently creating a dashboard style application that has multiple 'widgets' displaying various data. I have a parent component 'Dashboard' and this renders each of the 'Widget' components (which are dumb components) and the data is passed via props.
Now the problem I have is that in my 'Dashboard' component I am doing one ajax call to get the data for each Widget, on success of each ajax call I am calling setState() and pushing data in.
This appears to be correct from a design pattern perspective, but obviously calling setState will causes cascade re-renders, so each widget is being re-rendered in my case 10 times (as I have 10 widgets).
What am I doing so wrong here? Is my app now a candidate for Flux or Redux type architecture?
Edit: Code below
Parent component
/**
* Ajax calls (10 different calls, wont list them, all very similar)
*/
getRecent: function (url, limit) {
$.get(url, function (res) {
var data = res.response;
var products = [];
if (data.itemListInfo.numberOfItems > 0) {
for (var i = 0, j = limit; i < j; i++) {
products.push({
name: data.userItems[i].product.name,
itemCode: data.userItems[i].product.itemCode,
img: data.userItems[i].product.thumbnailImage,
});
}
}
// Obviously this is causing render() to fire
this.setState({
recent: {
numberOfItems: data.itemListInfo.numberOfItems,
products: products
}
});
setTimeout(function () {
$('#account-recent .loading').fadeOut();
}, 500);
}.bind(this));
},
componentDidMount: function () {
this.getReviews(this.config.reviews.url); // causes a render()
this.getRecent('/api/user/purchases/list', 3); // causes a render()
this.getRecommended('/api/user/recommendations/list', 3); // causes render()
this.getPreferences('/api/user/preferences/list'); //causes render()
// More ajax calls here....
},
render: function () {
return (
<Reviews data={this.state.reviews}/>
<Recommended data={this.state.recommended}/>
<RecentlyPurchased data={this.state.recent}/>
<Preferences data={this.state.preferences}/>
)
}
If I was to put a console.log('rendering...') in one of the children's render methods it would display a number of times depending on what position it is in the ajax call stack
Upvotes: 0
Views: 4176
Reputation: 1501
As you mentioned, you store information about all widgets in parent widget, so when the state changes, it triggers children update, what is expected behavior. Since there are no code, it is hard to identify your case, but there are some for you:
ImplementshouldComponentUpdate
method, so widget will be updated only if it receives changed props.
Do 1 ajax call to get the information for all the widgets, so you would have only 1 call and 1 update.
You can use redux or mobx and connect your widgets to a state, then it will be re-rendered only if the props passed to the widget were changed.
It would be easier to help if you write more code.
Upvotes: 2