Possiedo un'applicazione iOS con nativo react. La classe Game contiene un componente ListView. Ho impostato lo stato nel costruttore e include dataSource
. Ho una matrice di dati hardcoded per ora che memorizzo in una proprietà di stato diversa (this.state.ds
). Quindi nel componentDidMount
utilizzo il metodo cloneWithRows
per clonare il mio this.state.ds
come dataSource per la visualizzazione. Questo è abbastanza standard per quanto riguarda ListViews e funziona bene. Ecco il codice:Visualizzazione elenco aggiornamento nativo DataSource
/**
* 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
Il problema che sto avendo entra nel metodo pressRow
. Quando l'utente preme la riga, desidero che la selezione cambi e che apporti la modifica sul dispositivo. Attraverso alcune operazioni di debug, ho notato che anche se sto modificando la proprietà Selection
dell'oggetto nell'array newDs
, le stesse modifiche di proprietà sull'oggetto in this.state.ds
e analogamente viene modificato l'oggetto in this.state.dataSource._dataBlob.s1
. Attraverso ulteriori debug, ho scoperto che dal momento che quegli altri array sono stati modificati, l'oggetto DataSource di ListView non riconosce la modifica perché quando si imposta lo stato e viene chiamato rowHasChanged
, la matrice che clonazione corrisponde all'array this.state.dataSource._dataBlob.s1
e quindi non lo fa t sembra un cambiamento e non ritorna.
Qualche idea?
Grazie mille! C'era un altro passo che dovevo fare per farlo funzionare. Per qualche ragione ho dovuto "cancellare" l'oggetto che stavo cercando di cambiare. Così ho reso 'newDs [0]' uguale a un nuovo oggetto e gli ho dato le proprietà dell'oggetto che stavo cercando di cambiare. Ovviamente ho cambiato la proprietà 'Selection' però. –
Cambia 'this.state.ds.slice()' in 'this.state.ds.slice (0)' per prestazioni migliori. – TheNickyYo
@TheNickyYo - perché è così? I documenti dichiarati indefiniti vengono trattati come 0 in ogni caso? –