I have a ListView
, which, obviously, renders list of some items. Before, I was using React Native without Redux, so when my underlying data changes, I was calling setState()
, modifying the data, then dataSource = dataSource.cloneWithRows(itemsData);
, and it was quite performant: each row was re-rendered if only its data changes (i.e. if my rowHasChanged()
returned true
for that row).
But, the overall application design was quite ad-hoc and not very well maintainable, so I decided to try Redux.
Now, my scene is "pure", that is, it depends solely on the passed props, which are generated by means of mapStateToProps()
. But the problem is that whenever any item changes, the whole ListView
element is recreated, therefore, all items are re-rendered (my rowHasChanged()
is not even called). This is quite frustrating, since the only way to get rid of this behaviour is to make the scene non-pure again: add the state, and somehow update it when needed.
Or, what are other alternatives?
You can prevent unnecessary re-render by making your own check in shouldComponentUpdate. Also, to speed up comparison by making a shallow compare only, try making your data immutable with a library like Immutable.js.
Here is an example using ListView.DataSource and an immutable dataset taken from this article:
// Use immutable.is() to achieve efficient change detection.
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => !immutable.is(r1, r2)
})
// Shallow convert to a JS array, leaving immutable row data.
this.state = {
dataSource: ds.cloneWithRows(countries.toArray())
}
In redux
, when connecting your component, make sure to use mapStateToProps()
to filter your data. By using this technique, and passing the relevant props only, you probably won't even have to use shouldComponentUpdate
.
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