0
votes

I'm having problems getting a List View to update on it's own. I have some dummy data and an image that I would like to render a checked off image or unchecked image. The List View renders properly I just don't get an automatic re-render from the list view on press.

I have this in the getInitialState function:

var ds = new ListView.DataSource({
  rowHasChanged: (r1, r2) => r1 != r2
})

var dummyData = this.props.navigator.dummyData;
var formattedData = this.formatData(dummyData);

return ({
  data: formattedData,
  dataSource: ds.cloneWithRows(formattedData),
  selectedRow: {}.
})

formatData: function(data){...} // code to format data, it is working as intended

In my render I have this:

render:function() {
  return(
     <View>
       <ListView
         style={{flex:10}}
         dataSource={this.state.dataSource}
         renderRow={this.renderRow}
         renderSeperator={this.renderSeperator}
         enableEmptySections={true}
        />
     </View>
 )
}

renderRow:

 renderRow: function(rowData) {
  return(
  <TouchableHighlight onPress={() => {this.selectRow(rowData)} } >
  <View style={{borderLeftWidth: 8, borderLeftColor: '#81BD41'}}>
     <View style={styles.scheduleRow}>

      <View style={styles.shiftTextContainer}>
        <Text style={styles.textName}>
          {rowData.firstName} {rowData.lastName}
        </Text>
      </View>

      <View style={styles.checkedContainer}>
        {this.imageCheck(rowData)}
      </View>

    </View>
  </View>
  </TouchableHighlight>

On Press selectRow

  selectRow: function(rowData) {

    console.log(this.state.selectedRow == rowData);
    var copyData = this.state.data;

    if (this.state.selectedRow === rowData) {
      this.setState({selectedRow:''});
      rowData.selected = false;
    } else {
      this.setState({selectedRow: rowData})
      rowData.selected = true;
    }

    this.setState({dataSource: this.state.dataSource.cloneWithRows(copyData)});
    this.renderRow(rowData);
  },

And finally image check:

  imageCheck: function(rowData) {
    var image = '';

    if (this.state.selectedRow === rowData) {
      image = checkedImage;
    } else {
      image = uncheckedImage;
    }

    return (
      <View>
        <Image style={styles.imageSize} source={image} />
      </View>
    )
  },

I've tried manually calling the listview renderRow function as well as making a copy of the 'new data' and using cloneWithRows back into this.state.dataSource. I cannot get the image check mark to refresh automatically. If I save the project it renders the listview appropriately through hot reloading.

What am I doing wrong here? I suspect it's either I have to use onVisibleChange function for the ListView to get the render to automatically fire or change the rowHasChanged in my initial state to reflect the change more appropriately. But, I hear onVisibleChange has some bugs for the android side, so unless that's the only solution I do not want to use that to fix this bug.

Thank you for your time.

1
where are checkedImage and uncheckedImage defined? - FuzzyTree
It's just 'imports' using require for images I want to display based on the conditional logic. They work fine :D. I've omitted most of the things that I'm pretty sure are not the problem. - powerup7

1 Answers

0
votes

Try adding id in your rows, do not compare rowData directly, also you don't have to add this.renderRow(rowData); in your selectRow function. Your code will look like this:

renderRow: function(rowData) {
    return(
       <TouchableHighlight onPress={() => {this.selectRow(rowData.id)} } >
       ...
    );
}

selectRow( rowId ){

    this.setState({selectedRow:rowId});
}

imageCheck(){

    if (this.state.selectedRow == rowData.id){
        image = checkedImage;
    }
    else{
        image = uncheckedImage;
    }

    return (
      <View>
        <Image style={styles.imageSize} source={image} />
      </View>
    );
}