react-native: [0.19][ListView][Android] ListView crashes when ListView.DataSource is updated (with example code)
Updating a ListView.DataSource on Android causes a NullPointerException if list is long enough that it does not all fit on screen.
Here’s a sample project with code that illustrates the bug: https://github.com/npomfret/react-native-bug-reports/tree/master/ListViewUpdatingBug
It does not appear to happen on IOS.

Exception in native call from JS java.lang.NullPointerException: Attempt to read from field 'int android.view.ViewGroup$LayoutParams.width' on a null object reference at android.widget.TextView.checkForRelayout(TextView.java:7128) at android.widget.TextView.setText(TextView.java:4342)
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Comments: 19 (7 by maintainers)
I updated the reproduction from @npomfret to 0.21 and the issue still happens.
Through testing, I found a few workarounds:
renderScrollComponent={(props) => <React.RecyclerViewBackedScrollView {...props}/>}Now, from the docs:
So it looks like the solution is already documented; however I’d argue that making the results of renderRow require a certain style setting to work by default is not the friendliest option. I’d say that applying that style to the result of renderRow would be a reasonable solution, but until that change is made setting the default back to false for removeClippedSubviews would work.
I have the same problem with my ListView Footer. Never encountered something like that before. I’m on 0.22.0. If I have some variable in a textfield, it is not working anymore.
renderFooter:
thanks to @apalmblad for the workaround with removeClippedSubviews or overflow: hidden, both are working for me 👍
edit: what is better for the performance, setting overflow or removeClippedSubviews?
Set the data source to empty array before changing. It works. var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); this.setState({dataSource: ds.cloneWithRows([])}); this.setState({dataSource: ds.cloneWithRows(data)});
I tried that and it broke my pull to refresh. I had to do removeClippedSubviews={false} to fix the issue
Setting the datasource to an empty array may work but I believe it will cause flicker because the UI will clear itself out before redrawing your non-empty data set.
I’ve found that setting the
renderScrollComponentto anything other than the default is a satisfactory workaround. In my case I’ve used:renderScrollComponent={props => <RecyclerViewBackedScrollView />}.