ListView does not render correctly when row moved to above the current scroll position
See original GitHub issueFor a ListView with multiple headers and enough data to scroll, if the list is scrolled to the bottom and an item is added at the top (above the viewable area), then the ListView renders rows and headers on top of each other (or sometimes just really close to each other). Also, there will be empty spaces where presumably one of those rows/headers belong.
Note that if you modify the example to either have 1 header or use cloneWithRows with no headers, the problem seems to go away.
This was not a problem in RN 0.25.1 but is a problem as of v0.31.0-rc.0. I tested on iPhone 6s, both simulator and real device.
To reproduce, run the following code on an iPhone 6s, scroll all the way to the bottom, and click on a row near the bottom, then scroll back up and feast your eyes on the disaster. For best results, click on a few rows.
componentWillMount: function() {
this._listData = {
"header 1": [
"item 1",
"item 2",
"item 3",
"item 4",
"item 5",
"item 6",
"item 7",
"item 8",
"item 9",
"item 10",
"item 11",
"item 12",
"item 13",
"item 14",
"item 15",
"item 16",
"item 17",
"item 18",
"item 19",
"item 20",
"item 21",
"item 22",
"item 23",
"item 24",
"item 25",
"item 26",
"item 27",
"item 28",
"item 29",
],
"header 2": [
"item 30",
"item 31",
"item 32",
"item 33",
"item 34",
"item 35",
"item 36",
"item 37",
"item 38",
"item 39",
"item 40",
"item 41",
"item 42",
"item 43",
"item 44",
"item 45",
"item 46",
"item 47",
"item 48",
"item 49",
"item 50",
"item 51",
"item 52",
"item 53",
"item 54",
"item 55",
"item 56",
"item 57",
"item 58",
"item 59",
],
}
},
getInitalState: function() {
return {
ds: new ListView.DataSource( {
rowHasChanged: (r1, r2) => r1 !== r2,
sectionHeaderHasChanged: (s1, s2) => s1 !== s2
}
).cloneWithRowsAndSections(
this._listData
),
};
},
render: function() {
return (
<ListView
dataSource = { this.state.ds }
renderRow = {
( rowData, sectionId, rowId, highlightRow ) =>
{
return (
<Text
onPress = {
() => {
this._listData = JSON.parse( JSON.stringify( this._listData ) );
this._listData[sectionId].splice( rowId, 1 );
let newSection = Object.keys( this._listData )[ 0 ];
this._listData[newSection].unshift( rowData );
this.setState(
{
ds: this.state.ds.cloneWithRowsAndSections( this._listData )
}
);
}
}
style = {{padding:8}}
>
{ rowData }
</Text>
);
}
}
renderSectionHeader = { ( sectionData, sectionId ) => { return ( <Text> { "HEADER:" + sectionId } </Text>) } }
/>
);
},
Issue Analytics
- State:
- Created 7 years ago
- Reactions:2
- Comments:9 (1 by maintainers)
Scrolling above the content is a good workaround, but any idea when this will be fixed?
When debugging ListView/ScrollView components led me nowhere I decided to hack around the problem. One way that worked was switching scroll component on
renderScrollComponent
attribute with each change that would lead to rendering error. This forced redraw of the whole list.But the not-so-hacky workaround is just to scroll to the top of the list before actually modifying it, like so: