Angel Cuenca
Angel Cuenca

Reputation: 1659

Splice method in React

I'm trying to use splice to add new components into an array. If I use concat all the elements are added properly at the end, but what I also need is add at the beginning or in the middle of the array using splice. Any suggest ?

class App extends React.Component {
  state = {
    components: []
  };

  addNewElement = (element) => {      
    this.setState(prevState => ({   
      //Works fine
      //components: prevState.components.concat(element)

      components: prevState.components.splice(0, 0, element)
    }));
  };

}

Upvotes: 3

Views: 35499

Answers (3)

Dan Kreiger
Dan Kreiger

Reputation: 5516

splice() returns an array of elements that have been removed from the array. If no elements were removed, splice will return an empty array.

However, splice will change the contents of the array it's called on. You need to set the state on the updated array, not on what splice returns.

Try this method:

addNewElement(element) {
  this.state.components.splice(0, 0, element);
  this.setState({ components: this.state.components });
}

Below is a working snippet to demonstrate how you can insert a new element at a selected index using splice within a React component.

CodePen Demo

Upvotes: 3

Hamms
Hamms

Reputation: 5107

Be careful to note the difference between methods that mutate the array on which they are called and methods which returns mutated versions of the array on which they are called.

prevState.components.splice(0, 0, element) returns a new array containing the elements which have been removed, which for your purposes is going to be nothing.

Notably, splice also mutates the components array; mutating your State elements is A Bad Thing To Do; one simple way to avoid that is to create a clone of your array and splice that.

this.setState(prevState => {
  const components = prevState.components.slice(0);
  components.splice(0, 0, element);
  return { components };
});

This is functional, but relatively inelegant.

Other options you could consider would be to use React's immutability helper or use slice to divide your original array in two then concat all the bits together:

const i = // index at which to insert the new elements
const left = prevState.components.slice(0, i)
const right = prevState.components.slice(i)
return {
  components: left.concat(elements, right)
}

Upvotes: 2

kind user
kind user

Reputation: 41893

Array#splice works in situ and mutates the original array. You have to make a new instance (copy it) with Array#slice and then modify it.

addNewElement = (element) => {
   const newArr = prevState.components.slice();   
   newArr.splice(2, 0, 'foo');         // add 'foo` string at `2nd` index
   this.setState(prevState => ({   
      components: newArr;
   }));
};

Upvotes: 1

Related Questions