Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
70
rated 0 times [  75] [ 5]  / answers: 1 / hits: 52031  / 9 Years ago, fri, july 31, 2015, 12:00:00

I have an iOS app I am making with react-native. The Game class contains a ListView component. I set the state in the constructor and include a dataSource. I have a hardcoded array of data for right now that I store in a different state property (this.state.ds). Then in the componentDidMount I use the cloneWithRows method to clone my this.state.ds as my dataSource for the view. That is pretty standard as far as ListViews go and is working well. Here is the code:



/**
* 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)}
/>
);
}
}
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


The issue I am having comes in the pressRow method. When the user presses the row, I would like the selection to change and for it to render the change on the device. Through some debugging, I have noticed that even though I am changing the Selection property of the object in the newDs array, the same property changes on the object in this.state.ds and similarly changes the object in this.state.dataSource._dataBlob.s1. Through further debugging, I have found that since those other arrays have changed, the ListView's DataSource object doesn't recognize the change because when I set the state and rowHasChanged is called, the array it is cloning matches the array this.state.dataSource._dataBlob.s1 and so it doesn't look like a change and doesn't rerender.



Any ideas?


More From » ios

 Answers
4

Try this:



pressRow(rowData){

var newDs = [];
newDs = this.state.ds.slice();
newDs[0].Selection = newDs[0] == AwayTeam ? HomeTeam : AwayTeam;
this.setState({
dataSource: this.state.dataSource.cloneWithRows(newDs)
})

}


This should make a copy of the array, which can then be modified independently of the original array in this.state.ds.


[#65597] Wednesday, July 29, 2015, 9 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
zachary

Total Points: 175
Total Questions: 89
Total Answers: 108

Location: Fiji
Member since Wed, Jul 14, 2021
3 Years ago
;