React Native ListView не обновляется при изменении данных
Я не уверен, почему ListView не обновляется при изменении моих данных. Я разделил свой код, чтобы упростить чтение и создание rnplay:
https://rnplay.org/apps/ivG0mg
То, что я ожидаю, это то, что пользователь нажимает элемент списка, а строка bool isCollapsed
переключается, делая красный фон. На самом деле происходит обновление источника данных, но просмотр списка не распознает изменения и ничего нового не отображается. Любые идеи?
'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);
Ответы
Ответ 1
Здесь ссылка на рабочую версию:
https://rnplay.org/apps/GWoFWg
Это изменения, которые мне нужно внести, чтобы исправить это:
constructor(props){
super(props);
var ds = new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
});
this.state = {
dataSource: ds.cloneWithRows(foods),
db: foods,
};
}
и это:
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,
});
}
Ответ 2
Похоже, это решение, которое вам нужно
Список обновления обновленного списка данных DataSource
Но я немного поиграл с ним и не смог заставить его работать.
https://rnplay.org/apps/sk_ukQ
Не уверен, что это поможет, но я попробовал эту настройку массива как пустое и смог очистить весь список...
this.setState({dataSource: this.state.dataSource.cloneWithRows([])});
Я думаю, почему-то он использует кешированную версию исходного массива, а не обновленный массив. Просто не знаю почему.