Caleb Cheng
Caleb Cheng

Reputation: 33

Deleting a ListView item in React Native

I am having difficulty removing a row from a ListView. It removes the last element of the list, no matter which on is clicked. However, console.log tells me that the array has correctly deleted the item, but it renders wrongly... There are a few solutions already on the internet, but none have helped me solve my problem.

GIF of my problem

Logs

As you can see, it actually does remove the right item, but displays the wrong array?

Nov 6 22:18:39 Viviennes-Air reminders[25992] <Notice>: { rowID: '0' } Nov 6 22:18:39 Viviennes-Air reminders[25992] <Notice>: [ 'testing 2', 'testing 3' ] Nov 6 22:18:39 Viviennes-Air reminders[25992] <Notice>: { _rowHasChanged: [Function: rowHasChanged], _getRowData: [Function: defaultGetRowData], _sectionHeaderHasChanged: [Function], _getSectionHeaderData: [Function: defaultGetSectionHeaderData], _dataBlob: { s1: [ 'testing 2', 'testing 3' ] }, _dirtyRows: [ [ false, false, true ] ], _dirtySections: [ false ], _cachedRowCount: 3, rowIdentities: [ [ '0', '1', '2' ] ], sectionIdentities: [ 's1' ] }

Here's my constructor:

constructor(props) {
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
  items: [],
  dataSource: ds.cloneWithRows([]),
  newItem: "",
};}

The ListView:

<ListView
        style={styles.container}
        dataSource={this.state.dataSource}
        enableEmptySections={true}
        renderRow={(data, sectionID, rowID) => this.renderRow(data, sectionID, rowID)}
        renderSeparator={(sectionId, rowId) => <View key={rowId} style={styles.separator}/>}
      />

The renderRow function:

renderRow(data, sectionID, rowID){
console.log("ITEM: ", data)
return <TouchableOpacity style={styles.listItem} onPress={() => this._delete({rowID})}
            activeOpacity={0.1}>
            <Text style={styles.listItemText}>{data}</Text>
            </TouchableOpacity>}

And finally, the delete function:

_delete(index){
  this.state.items.splice(index, 1)
  console.log(index)
  console.log(this.state.items)
  this.setState({
    dataSource: this.state.dataSource.cloneWithRows(this.state.items)
  })
  console.log(this.state.dataSource)}

I have been trying to figure this our for 2 hours now, and I'm pretty sure I'm doing everything correctly.

Upvotes: 1

Views: 6092

Answers (1)

Jickson
Jickson

Reputation: 5193

I agree with Burak Karasoy, But there is another mistake in the code.

var newList= this.state.items.splice(index, 1)

newList will contain the deleted item, but actually what we need is new List after deleting the item.

So changes required to make your code work is,

Do not store items in state object. Instead store it as class instance variable and set the dataSource, like below code

this.items=this.getItems();
this.setState({
        dataSource: this.state.dataSource.cloneWithRows(this.items)
 });

Now update your _delete method like below

_delete(index) {
    this.items.splice(index, 1)// This will remove the element at index, and update this.items with new array
    this.setState({
      dataSource: this.state.dataSource.cloneWithRows(this.items)
    });
}

Upvotes: 3

Related Questions