I'm not sure why the ListView isn't updating when my data changes. I've striped my code down to make it easy to read and created a rnplay:
https://rnplay.org/apps/ivG0mg
What I expect to happen is, the user clicks the list item and the row's bool isCollapsed
is toggled making the background red. What actually happens is the datasource is updated but the list view doesn't recognize the change and nothing new is rendered. Any ideas?
'use strict';
var React = require('react-native');
var {
ScrollView,
Text,
Image,
StyleSheet,
TouchableHighlight,
AppRegistry,
View,
ListView,
} = React;
var styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
padding: 15,
},
red: {
backgroundColor: "red",
}
});
var foods = [
{key: 'Almond Milk (Homemade)', details:''},
{key: 'Club Soda', details:'', isCollapsed: true},
{key: 'Coconut Milk/Cream', details:''},
{key: 'Coconut Water', details:''},
{key: 'Coffee/Espresso', details:'', isCollapsed: true},
{key: 'Fruit Juice', details:''},
{key: 'Kombucha', details:''},
{key: 'Mineral Water', details:''},
{key: 'Unsweetened Tea', details:''},
{key: 'Water', details:''},
{key: 'Fruit Juice', details:''},
{key: 'Kombucha', details:''},
{key: 'Mineral Water', details:''},
{key: 'Unsweetened Tea', details:''},
{key: 'Water', details:''},
{key: 'Fruit Juice', details:''},
{key: 'Kombucha', details:''},
{key: 'Mineral Water', details:''},
{key: 'Unsweetened Tea', details:''},
{key: 'Water', details:''},
{key: 'Fruit Juice', details:''},
{key: 'Kombucha', details:''},
{key: 'Mineral Water', details:''},
{key: 'Unsweetened Tea', details:''},
{key: 'Water', details:''},
{key: 'Fruit Juice', details:''},
{key: 'Kombucha', details:''},
{key: 'Mineral Water', details:''},
{key: 'Unsweetened Tea', details:''},
{key: 'Water', details:''},
];
class SampleApp extends React.Component{
constructor(props){
super(props);
var ds = new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
});
this.state = {
dataSource: ds.cloneWithRows(foods),
};
}
_renderRow(data, sectionID, rowID) {
return (
<TouchableHighlight
style={[
styles.container,
data.isCollapsed && styles.red]}
onPress={()=>this.onCollapse(rowID)}>
<Text>{data.key}</Text>
</TouchableHighlight>
);
}
onCollapse(rowID: number) {
console.log("rowID", rowID);
foods[rowID].isCollapsed = !foods[rowID].isCollapsed;
this.setState({dataSource: this.state.dataSource.cloneWithRows(foods)});
}
render() {
return(
<ListView
style={styles.subContainer}
dataSource={this.state.dataSource}
renderRow={this._renderRow.bind(this)}
initialListSize={15}/>
)
}
};
AppRegistry.registerComponent('SampleApp', () => SampleApp);
Here's a link to a working version:
https://rnplay.org/apps/GWoFWg
These are the changes I need to make to fix it:
constructor(props){
super(props);
var ds = new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
});
this.state = {
dataSource: ds.cloneWithRows(foods),
db: foods,
};
}
and this:
onCollapse(rowID: number) {
var newArray = this.state.db.slice();
newArray[rowID] = {
key: newArray[rowID].key,
details: newArray[rowID].details,
isCollapsed: newArray[rowID].isCollapsed == false ? true : false,
};
this.setState({
dataSource: this.state.dataSource.cloneWithRows(newArray),
db: newArray,
});
}
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