Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How force redraw ListView when this.state changed (but not the dataSource).

I created a component that use a ListView to display a list of contacts. When clicking on a row, I update an array in the state's component that contains all the selected contacts. However, I'm not using this array as a dataSource for my ListView component.

I would like to redraw the ListView each time this array is modified in order to display an image for the selected contacts.

Here is an example of my current situation:

renderListView: function(){
    <ListView
        dataSource={this.state.dataSource}
        renderRow={this.renderRow}
        style={styles.listView}
    />
}
renderRow:function(row){
    return if(this.state.something === true) <Text>Something</Text>
   else <Text>Something Else</Text>
}

I tried to call .forceUpdate(), it calls the render method but not the renderRow method.

Any suggestion?

like image 340
Jean Lebrument Avatar asked Oct 30 '15 13:10

Jean Lebrument


1 Answers

I just had this same issue. Check out my question here: React Native ListView not updating on data change

Basically, there seems to be a bug with the ListView component and you need to rebuild each item that changes in the datasource for the ListView to redraw it.

Here's a working example: https://rnplay.org/apps/GWoFWg

First, create the datasource and a copy of the array and save them to state. In my case, foods is the array.

constructor(props){
    super(props);
    var ds = new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1 !== row2,
    });
    this.state = {
        dataSource: ds.cloneWithRows(foods),
        db: foods,
    };
}

When you want to change something in the datasource, make a copy of the array you saved to the state, rebuild the item with the change and then save the new array with the change back to the state (both db and datasource).

onCollapse(rowID: number) {
    console.log("rowID", rowID);
    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,
    });
}
like image 133
Dev01 Avatar answered Sep 26 '22 16:09

Dev01