Javascript 在组件状态下从数组中删除元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29527385/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Removing element from array in component state
提问by aherriot
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.statevariable directly, is there a better way (more concise) to remove an element from an array than what I have here?:
我试图找到从处于组件状态的数组中删除元素的最佳方法。由于我不应该this.state直接修改变量,是否有比我这里更好的方法(更简洁)从数组中删除元素?:
onRemovePerson: function(index) {
this.setState(prevState => { // pass callback in setState to avoid race condition
let newData = prevState.data.slice() //copy array from prevState
newData.splice(index, 1) // remove element
return {data: newData} // update state
})
},
Thank you.
谢谢你。
updated
更新
This has been updated to use the callback in setState. This should be done when referencing the current state while updating it.
这已更新为使用 setState 中的回调。这应该在更新它时引用当前状态时完成。
回答by ephrion
The cleanest way to do this that I've seen is with filter:
我见过的最干净的方法是filter:
removeItem(index) {
this.setState({
data: this.state.data.filter((_, i) => i !== index)
});
}
回答by Jonny Buchanan
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.
您可以使用update()来自react-addons-update的不变性助手,它实际上在幕后做同样的事情,但您所做的很好。
this.setState(prevState => ({
data: update(prevState.data, {$splice: [[index, 1]]})
}))
回答by pscl
I believe referencing this.stateinside of setState()is discouraged (State Updates May Be Asynchronous).
我相信不鼓励引用this.state内部setState()(状态更新可能是异步的)。
The docs recommend using setState()with a callback function so that prevState is passed in at runtime when the update occurs. So this is how it would look:
文档建议使用setState()回调函数,以便在更新发生时在运行时传入 prevState。所以这就是它的样子:
Using Array.prototype.filter without ES6
在没有 ES6 的情况下使用 Array.prototype.filter
removeItem : function(index) {
this.setState(function(prevState){
return { data : prevState.data.filter(function(val, i) {
return i !== index;
})};
});
}
Using Array.prototype.filter with ES6 Arrow Functions
在 ES6 箭头函数中使用 Array.prototype.filter
removeItem(index) {
this.setState((prevState) => ({
data: prevState.data.filter((_, i) => i !== index)
}));
}
Using immutability-helper
使用不变性助手
import update from 'immutability-helper'
...
removeItem(index) {
this.setState((prevState) => ({
data: update(prevState.data, {$splice: [[index, 1]]})
}))
}
Using Spread
使用点差
function removeItem(index) {
this.setState((prevState) => ({
data: [...prevState.data.slice(0,index), ...prevState.data.slice(index+1)]
}))
}
Note that in each instance, regardless of the technique used, this.setState()is passed a callback, notan object reference to the old this.state;
请注意,在每个实例中,无论使用何种技术,this.setState()都会传递一个回调,而不是旧的对象引用this.state;
回答by evianpring
Here is a way to remove the element from the array in the state using ES6 spread syntax.
这是一种使用 ES6 扩展语法从状态数组中删除元素的方法。
onRemovePerson: (index) => {
const data = this.state.data;
this.setState({
data: [...data.slice(0,index), ...data.slice(index+1)]
});
}
回答by c0d3ster
I want to chime in here even though this question has already been answered correctly by @psclin case anyone else runs into the same issue I did. Out of the 4 methods give I chose to use the es6 syntax with arrow functions due to it's conciseness and lack of dependence on external libraries:
即使@pscl已经正确回答了这个问题,我也想在这里插一句,以防其他人遇到我遇到的同样问题。在这 4 种方法中,我选择使用带有箭头函数的 es6 语法,因为它简洁且不依赖外部库:
Using Array.prototype.filter with ES6 Arrow Functions
在 ES6 箭头函数中使用 Array.prototype.filter
removeItem(index) {
this.setState((prevState) => ({
data: prevState.data.filter((_, i) => i != index)
}));
}
As you can see I made a slight modification to ignore the type of index (!==to !=) because in my case I was retrieving the index from a string field.
正如您所看到的,我做了一个轻微的修改以忽略索引的类型 ( !==to !=),因为在我的情况下,我是从字符串字段中检索索引。
Another helpful point if you're seeing weird behavior when removing an element on the client side is to NEVER use the index of an array as the key for the element:
如果您在客户端删除元素时看到奇怪的行为,另一个有用的点是永远不要使用数组的索引作为元素的键:
// bad
{content.map((content, index) =>
<p key={index}>{content.Content}</p>
)}
When React diffs with the virtual DOM on a change, it will look at the keys to determine what has changed. So if you're using indices and there is one less in the array, it will remove the last one. Instead, use the id's of the content as keys, like this.
当 React 与虚拟 DOM 发生变化时,它会查看键来确定发生了什么变化。因此,如果您使用索引并且数组中少了一个,它将删除最后一个。相反,像这样使用内容的 id 作为键。
// good
{content.map(content =>
<p key={content.id}>{content.Content}</p>
)}
The above is an excerpt from this answer from a related post.
以上是来自相关帖子的这个答案的摘录。
Happy Coding Everyone!
祝大家编码愉快!
回答by Matt Ellis
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.
正如上面对 ephrion 的回答的评论中所述, filter() 可能很慢,尤其是对于大型数组,因为它会循环查找似乎已经确定的索引。这是一个干净但效率低下的解决方案。
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!
希望这可以帮助!
回答by julian libor
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)
});
}
回答by Brian Burns
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) }));
回答by T04435
Here is a simple way to do it:
这是一个简单的方法:
removeFunction(key){
const data = {...this.state.data}; //Duplicate state.
delete data[key]; //remove Item form stateCopy.
this.setState({data}); //Set state as the modify one.
}
Hope it Helps!!!
希望能帮助到你!!!

