0

To delete element from an array without mutating the state I write this code below which work fine

const tmp = [ ...array ]
tmp.splice(i, 1)
setArray(tmp)

I played a little bit with the code and i try this

array.splice(i, 1)
setArray([ ...array ])

But I got a weird behavior in the UI.

So What is wrong with this code, because i think i am not mutating the state, am I ?

Hayi
  • 6,972
  • 26
  • 80
  • 139

1 Answers1

3

splice mutates the existing array:

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

In the first code, you've created a copy of the array first, so what gets mutated is not the object in state, so everything's fine. But in the second code, you're mutating the original array, which is a problem if you need things to be immutable. (Despite the fact that you then spread a copy of the mutated original array, the original array has still been mutated.)

For example:

const setArray = (newArray) => {
  // do something
};

const array = [1, 2, 3, 4];
const i = 2;

array.splice(i, 1)
setArray([ ...array ])

// Original array has been mutated:
console.log(array);

You could also use slice instead:

const newArr = array.slice(0, i).concat(i + 1);
setArray(newArr);
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • correct me if i am wrong but in reactjs the important thing is to pass a new object in the state otherwise the UI will not rendered, that's why i am passing a new array even if i mutate the original array before – Hayi Oct 10 '19 at 00:58
  • 1
    It's technically possible to mutate a prior state before calling `setState` again, in certain circumstances, but it should [probably always be avoided](https://stackoverflow.com/questions/37755997/), because even if it doesn't create trouble for you now, it may later. (The *weird behavior in the UI* you describe may well be trouble caused by directly mutating now) – CertainPerformance Oct 10 '19 at 01:12