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
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)
});
}
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 dummyArray = [];
this.setState({data: dummyArray.concat(this.state.data.slice(0, index), this.state.data.slice(index))})
Hope this helps!
You could make the code more readable with a one line helper function:
const removeElement = (arr, i) => [...arr.slice(0, i), ...arr.slice(i+1)];
then use it like so:
this.setState(state => ({ places: removeElement(state.places, index) }));
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)]
});
}
Just a suggestion,in your code instead of using let newData = prevState.data
you could use spread which is introduced in ES6 that is you can uselet newData = ...prevState.data
for copying array
Three dots ... represents Spread Operators or Rest Parameters,
It allows an array expression or string or anything which can be iterating to be expanded in places where zero or more arguments for function calls or elements for array are expected.
Additionally you can delete item from array with following
onRemovePerson: function(index) {
this.setState((prevState) => ({
data: [...prevState.data.slice(0,index), ...prevState.data.slice(index+1)]
}))
}
Hope this contributes!!
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(prevState => ({
data: update(prevState.data, {$splice: [[index, 1]]})
}))