У меня есть приложение iOS, которое я делаю с реакцией. Класс Game содержит компонент ListView. Я устанавливаю состояние в конструкторе и включаю dataSource
. У меня есть жестко заданный массив данных прямо сейчас, когда я храню другое свойство состояния (this.state.ds
). Затем в componentDidMount
я использую метод cloneWithRows
для клонирования моего this.state.ds
в качестве моего источника данных для представления. Это довольно стандартно, поскольку ListViews идет и работает хорошо. Вот код:
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
'use strict';
var React = require('react-native');
var {
StyleSheet,
Text,
View,
ListView,
TouchableHighlight
} = React;
class Games extends React.Component{
constructor(props){
super(props);
var ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 != r2
});
this.state = {
ds:[{AwayTeam: "TeamA", HomeTeam: "TeamB", Selection: "AwayTeam"},{AwayTeam: "TeamC", HomeTeam: "TeamD", Selection: "HomeTeam"}],
dataSource:ds,
}
}
componentDidMount(){
this.setState({
dataSource:this.state.dataSource.cloneWithRows(this.state.ds),
})
}
pressRow(rowData){
var newDs = [];
newDs = this.state.ds;
newDs[0].Selection = newDs[0] == "AwayTeam" ? "HomeTeam" : "AwayTeam";
this.setState({
dataSource: this.state.dataSource.cloneWithRows(newDs)
})
}
renderRow(rowData){
return (
<TouchableHighlight
onPress={()=> this.pressRow(rowData)}
underlayColor = '#ddd'>
<View style ={styles.row}>
<Text style={{fontSize:18}}>{rowData.AwayTeam} @ {rowData.HomeTeam} </Text>
<View style={{flex:1}}>
<Text style={styles.selectionText}>{rowData[rowData.Selection]}</Text>
</View>
</View>
</TouchableHighlight>
)
}
render(){
return (
<ListView
dataSource = {this.state.dataSource}
renderRow = {this.renderRow.bind(this)}>
</ListView>
);
}
}
var styles = StyleSheet.create({
row:{
flex:1,
flexDirection:'row',
padding:18,
borderBottomWidth: 1,
borderColor: '#d7d7d7',
},
selectionText:{
fontSize:15,
paddingTop:3,
color:'#b5b5b5',
textAlign:'right'
},
});
module.exports = Games
Проблема, с которой я столкнулась, приходит в методе pressRow
. Когда пользователь нажимает на строку, я хочу, чтобы выбор изменился, и чтобы он отображал изменения на устройстве. Через некоторую отладку я заметил, что, хотя я изменяю свойство Selection
объекта в массиве newDs
, такое же свойство изменяется на объекте в this.state.ds
и аналогичным образом изменяет объект в this.state.dataSource._dataBlob.s1
. После дальнейшей отладки я обнаружил, что, поскольку эти другие массивы были изменены, объект ListView DataSource не распознает изменение, потому что, когда вызывается состояние и rowHasChanged
вызывается, массив, который он клонирует, соответствует массиву this.state.dataSource._dataBlob.s1
и так что это не похоже на изменение и не ререйдер.
Любые идеи?