181

The story is, I should be able to put Bob, Sally and Jack into a box. I can also remove either from the box. When removed, no slot is left.

people = ["Bob", "Sally", "Jack"]

I now need to remove, say, "Bob". The new array would be:

["Sally", "Jack"]

Here is my react component:

...

getInitialState: function() {
  return{
    people: [],
  }
},

selectPeople(e){
  this.setState({people: this.state.people.concat([e.target.value])})
},

removePeople(e){
  var array = this.state.people;
  var index = array.indexOf(e.target.value); // Let's say it's Bob.
  delete array[index];
},

...

Here I show you a minimal code as there is more to it (onClick etc). The key part is to delete, remove, destroy "Bob" from the array but removePeople() is not working when called. Any ideas? I was looking at this but I might be doing something wrong since I'm using React.

Community
  • 1
  • 1
Sylar
  • 8,631
  • 20
  • 72
  • 139

13 Answers13

257

When using React, you should never mutate the state directly. If an object (or Array, which is an object too) is changed, you should create a new copy.

Others have suggested using Array.prototype.splice(), but that method mutates the Array, so it's better not to use splice() with React.

Easiest to use Array.prototype.filter() to create a new array:

removePeople(e) {
    this.setState({people: this.state.people.filter(function(person) { 
        return person !== e.target.value 
    })});
}
Chance Smith
  • 987
  • 1
  • 11
  • 30
iaretiga
  • 3,815
  • 1
  • 10
  • 9
  • 48
    Yes this is declarative way. An alternate method using prevState and arrow functions: `this.setState(prevState => ({ people: prevState.people.filter(person => person !== e.target.value) }));` – Josh Morel Apr 15 '17 at 16:57
  • 9
    This should be the accepted answer per the React idiom of never mutating state. – lux Jan 03 '18 at 15:53
  • 11
    or using the index: `this.state.people.filter((_, i) => i !== index)` – mb21 May 28 '18 at 12:11
  • 2
    there is slice that is imutable and splice that mutable – Cassian Jun 21 '18 at 17:51
  • Issue with this answer is if you have several persons with the same name, you will remove all of these. Using the index is safer in cases where you may have dupes – klugjo Jan 25 '19 at 14:33
  • @Cassian omg thanks. Took me a while to finally find this info... I couldn't tell the small difference (1 character) between splice and slice. I was using slice but had read about splice.. Sigh. – Elizandro - SparcBR Jun 18 '20 at 04:05
240

To remove an element from an array, just do:

array.splice(index, 1);

In your case:

removePeople(e) {
  var array = [...this.state.people]; // make a separate copy of the array
  var index = array.indexOf(e.target.value)
  if (index !== -1) {
    array.splice(index, 1);
    this.setState({people: array});
  }
},
MarcoS
  • 15,673
  • 23
  • 78
  • 152
  • 4
    In my case it was: `array.splice(array, 1);` Thanks – Sylar Mar 31 '16 at 07:49
  • `array.splice(array, 1);` ? I guess you need to edit it..You should be using different variables... – Rayon Mar 31 '16 at 07:50
  • 72
    When using React, you should generally avoid mutating your state directly. You should create a new Array and use `setState()`. – iaretiga Mar 31 '16 at 08:02
  • Every answer partially works but when another person's 'remove' button is clicked, it removes the wrong person. [b]Aleksandr Petrov's[/b] works best but it leaves `null` values in the array so I used `array.splice(index, 1);` instead. Sending a thanks to [b]Aleksandr Petrov[/]b]. Your answer works so let's make a slight adjustment to the answer. – Sylar Mar 31 '16 at 08:16
  • What if I have another state object other than people? will it be discarded? – funky-nd May 20 '18 at 04:44
  • 2
    I recommend using Array.from(this.state.items) instead of the spread operator in this case. This is because Array.from is specifically intended for this use. – Francisco Hodge Jun 14 '18 at 14:19
  • what is 'e' in this case? what value should i pass to call removePeople() function? I'm sorry if its a very basic question but I'm just a learner. – Rajwant Kaur Boughan Oct 09 '18 at 04:42
  • 2
    Small suggestion, add a check for "index !== -1" before splicing the array to prevent unwanted removals. – RoboBear Nov 07 '18 at 18:04
  • This is anti-patten. The splice function mutates or change the same – ibsenv Nov 23 '19 at 10:29
  • this must be the worst thing about react native – jsnid00 Dec 09 '20 at 20:10
47

Here is a minor variation on Aleksandr Petrov's response using ES6

removePeople(e) {
    let filteredArray = this.state.people.filter(item => item !== e.target.value)
    this.setState({people: filteredArray});
}
Dmitry
  • 3,161
  • 6
  • 40
  • 48
18

Use .splice to remove item from array. Using delete, indexes of the array will not be altered but the value of specific index will be undefined

The splice() method changes the content of an array by removing existing elements and/or adding new elements.

Syntax: array.splice(start, deleteCount[, item1[, item2[, ...]]])

var people = ["Bob", "Sally", "Jack"]
var toRemove = 'Bob';
var index = people.indexOf(toRemove);
if (index > -1) { //Make sure item is present in the array, without if condition, -n indexes will be considered from the end of the array.
  people.splice(index, 1);
}
console.log(people);

Edit:

As pointed out by justin-grant, As a rule of thumb, Never mutate this.state directly, as calling setState() afterward may replace the mutation you made. Treat this.state as if it were immutable.

The alternative is, create copies of the objects in this.state and manipulate the copies, assigning them back using setState(). Array#map, Array#filter etc. could be used.

this.setState({people: this.state.people.filter(item => item !== e.target.value);});
Rayon
  • 34,175
  • 4
  • 40
  • 65
  • 3
    Make sure not to use splice or any method that changes your state variable directly. Instead, you'll want to make a copy of the array, remove the item from the copy, and then pass the copy into `setState`. Other answers have details about how to do this. – Justin Grant May 22 '19 at 23:47
17

Easy Way To Delete Item From state array in react:

when any data delete from database and update list without API calling that time you pass deleted id to this function and this function remove deleted recored from list

export default class PostList extends Component {
  this.state = {
      postList: [
        {
          id: 1,
          name: 'All Items',
        }, {
          id: 2,
          name: 'In Stock Items',
        }
      ],
    }


    remove_post_on_list = (deletePostId) => {
        this.setState({
          postList: this.state.postList.filter(item => item.post_id != deletePostId)
        })
      }
  
}
ANKIT DETROJA
  • 1,072
  • 10
  • 19
3

Some answers mentioned using 'splice', which did as Chance Smith said mutated the array. I would suggest you to use the Method call 'slice' (Document for 'slice' is here) which make a copy of the original array.

3

It's Very Simple First You Define a value

state = {
  checked_Array: []
}

Now,

fun(index) {
  var checked = this.state.checked_Array;
  var values = checked.indexOf(index)
  checked.splice(values, 1);
  this.setState({checked_Array: checked});
  console.log(this.state.checked_Array)
}
Joey Ciechanowicz
  • 2,711
  • 3
  • 19
  • 45
QC innodel
  • 39
  • 6
2
removePeople(e){
    var array = this.state.people;
    var index = array.indexOf(e.target.value); // Let's say it's Bob.
    array.splice(index,1);
}

Redfer doc for more info

Olcay Ertaş
  • 5,374
  • 8
  • 71
  • 98
Gibbs
  • 16,706
  • 11
  • 53
  • 118
2
const [people, setPeople] = useState(data);

const handleRemove = (id) => {
   const newPeople = people.filter((person) => { person.id !== id;
     setPeople( newPeople );
     
   });
 };

<button onClick={() => handleRemove(id)}>Remove</button>
Glover
  • 21
  • 4
1

You forgot to use setState. Example:

removePeople(e){
  var array = this.state.people;
  var index = array.indexOf(e.target.value); // Let's say it's Bob.
  delete array[index];
  this.setState({
    people: array
  })
},

But it's better to use filter because it does not mutate array. Example:

removePeople(e){
  var array = this.state.people.filter(function(item) {
    return item !== e.target.value
  });
  this.setState({
    people: array
  })
},
Aleksandr Petrov
  • 1,242
  • 9
  • 13
0

I also had a same requirement to delete an element from array which is in state.

const array= [...this.state.selectedOption]
const found= array.findIndex(x=>x.index===k)
if(found !== -1){
   this.setState({
   selectedOption:array.filter(x => x.index !== k)
    })
 }

First I copied the elements into an array. Then checked whether the element exist in the array or not. Then only I have deleted the element from the state using the filter option.

Senthuran
  • 693
  • 9
  • 14
0
const array = [...this.state.people];
array.splice(i, 1);
this.setState({people: array});         
Tomerikoo
  • 12,112
  • 9
  • 27
  • 37
0

Almost all the answers here seem to be for class components, here's a code that worked for me in a functional component.

const [arr,setArr]=useState([]);
const removeElement=(id)=>{
    var index = arr.indexOf(id)
    if(index!==-1){
      setArr(oldArray=>oldArray.splice(index, 1));
    }
}
Shardul Birje
  • 150
  • 4
  • 13