Home » Reactjs » Removing element from array in component state

Removing element from array in component state

Posted by: admin November 29, 2017 Leave a comment

Questions:

I am trying to find the best way to remove an element from an array in the state of a component. Since I should not modify the this.state variable directly, is there a better way (more concise) to remove an element from an array than what I have here?:

  onRemovePerson: function(index) {
    var newData = this.state.data.slice(); //copy array
    newData.splice(index, 1); //remove element
    this.setState({data: newData}); //update state
  },

Thank you.

Answers:

You could use the update() immutability helper from react-addons-update, which effectively does the same thing under the hood, but what you’re doing is fine.

this.setState({
  data: update(this.state.data, {$splice: [[index, 1]]})
})

Questions:
Answers:

The cleanest way to do this that I’ve seen is with filter:

removeItem(index) {
  this.setState({
    data: this.state.data.filter((_, i) => i !== index)
  });
}

Questions:
Answers:

I believe referencing this.state inside of setState() is discouraged
https://facebook.github.io/react/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous

The docs recommend using setState() with a callback function so that prevState is passed in at runtime when the update occurs. So this is how it would look:

Using Array.prototype.filter without ES6

removeItem : function(index) {
  this.setState(function(prevState){
    return { data : prevState.data.filter(function(val, i) {
      return i !== index;
    })};
  });
}

Using Array.prototype.filter with ES6 Arrow Functions

removeItem(index) {
  this.setState((prevState) => ({
    data: prevState.data.filter((_, i) => i !== index)
  }));
}

Using immutability-helper

import update from 'immutability-helper'
...
removeItem(index) {
  this.setState((prevState) => ({
    data: update(prevState.data, {$splice: [[index, 1]]})
  }))
}

Using Spread

function removeItem(index) {
  this.setState((prevState) => ({
    data: [...prevState.data.slice(0,index), ...prevState.data.slice(index+1)]
  }))
}

Note that in each instance, regardless of the technique used, this.setState() is passed a callback, not an object reference the old this.state;

Questions:
Answers:

Here is a way to remove the element from the array in the state using ES6 spread syntax.

onRemovePerson: (index) => {
  const data = this.state.data;
  this.setState({ 
    data: [...data.slice(0,index), ...data.slice(index+1)]
  });
}

Questions:
Answers:

As mentioned in a comment to ephrion’s answer above, filter() can be slow, especially with large arrays, as it loops to look for an index that appears to have been determined already. This is a clean, but inefficient solution.

As an alternative one can simply ‘slice’ out the desired element and concatenate the fragments.

    var dummayArray = [];    
    this.setState({data:dummyArray.concat(this.state.data.slice(0,index),this.state.data.slice(index))})

Hope this helps!

Questions:
Answers:

You can use this function, if you want to remove the element (without index)

removeItem(item) {
  this.setState(prevState => {
    data: prevState.data.filter(i => i !== item)
  });
}

Questions:
Answers:

I am using this, hope it has no issue and help.

    removeItem(item){
        const index = this.state.yourArray.indexOf(item);
        if (index < 0 ) return
        this.state.yourArray.splice(index, 1)
        this.setState({yourArray: this.state.yourArray})
    }

Questions:
Answers:

Here is a simple way to do it:

removeFunction(key){
  const data = {...this.state.data}; //Duplicate state.
  delete data[key];                  //remove Item form stateCopy.
  this.setState({data});             //Set state as the modify one.
}

Hope it Helps!!!