Reputation: 1659
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
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.
Upvotes: 3
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
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