[英]react push unique objects in array
I have a function that is supposed to add unique elements to an array: 我有一个应该向数组添加唯一元素的函数:
addLanguage = (val) => {
for(let i=0; i< val.length; i++){
console.log(val[i].id)
if(this.state.createNewDeliveryData.languages.indexOf(val[i].id === -1)){
this.state.createNewDeliveryData.languages.push(val[i])
}
}
}
the argument 'val' each time gets an array with appended elements (I have a multi select box on UI from where I add languages), that's why in If loop I am trying to check if my languages array already has that specific element. 参数val每次都会得到一个带有附加元素的数组(我从中添加语言的UI上有一个多选框),这就是为什么在If循环中我试图检查我的语言数组是否已经具有该特定元素。 However this has no effect and at the end my languages array contains same elements ie same element is added twice or thrice etc. on subsequent calls. 但是,这没有任何效果,最后,我的语言数组包含相同的元素,即在后续调用中将相同的元素添加两次或三次。
['German']
['German', 'German', 'Arabic']
...
What am I doing wrong? 我究竟做错了什么?
You are looking for the index of false
in your array. 您正在寻找数组中的false
索引。 That's because, indexOf(val[i].id === -1)
will always check indexOf(false)
which is -1. 这是因为indexOf(val[i].id === -1)
将始终检查indexOf(false)
。 So you re-add each language. 因此,您需要重新添加每种语言。
You are probably after an algorithm more similar to this: 您可能正在寻找一种更类似于此的算法:
addLanguage = (val) => {
// Get a copy of the languages state.
const languages = [...this.state.createNewDeliveryData.languages];
for(let i=0; i< val.length; i++){
if(languages.indexOf(val[i].id) === -1) { // notice that there is a parenthesis after `id`.
languages.push(val[i].id)
}
}
this.setState({createNewDeliveryData: {languages}}); // update state and trigger re-render if there are new languages.
}
Note that you should always use setState
to mutate the state in react. 请注意,您应始终使用setState
更改react中的状态。
You have a few issues with your code: 您的代码有一些问题:
First of all, never, ever mutate this.state
directly. 首先, 永远 this.state
直接this.state
。 It is anti-pattern and may yield undesired results. 这是反模式,可能会产生不希望的结果。 Use this.setState()
instead. 请改用this.setState()
。
There is no need to do indexOf
in a loop. 无需在循环中执行indexOf
。 indexOf
will iterate the array and return the index of the searched item, or -1
if it was not in the array. indexOf
将迭代该数组并返回搜索到的项目的索引;如果它不在数组中,则返回-1
。
You have to create a copy for the this.state.createNewDeliveryData
object and for the languages
array. 您必须为this.state.createNewDeliveryData
对象和 languages
数组创建一个副本。
That said, one solution could be: 也就是说,一种解决方案可能是:
addLanguage = (val) => {
if(this.state.createNewDeliveryData.languages.indexOf(val) === -1) {
let obj = Object.assign({}, this.state.createNewDeliveryData); //shallow-copy object
let arr = obj.languages.slice(); //copy array
arr.push(val); //push the value
obj.languages = arr; //assign the new array to our copied object
this.setState({createNewDeliveryData: obj}); //replace the old object with the new
}
}
or in a more compact form: 或更紧凑的形式:
addLanguage = (val) => {
if(this.state.createNewDeliveryData.languages.indexOf(val) === -1) {
let obj = Object.assign({}, this.state.createNewDeliveryData); //shallow-copy object
obj.languages = obj.languages.slice().push(val);
this.setState({createNewDeliveryData: obj}); //replace the old object with the new
}
}
Instead of checking each element in a loop, you could just use Set
object to remove every duplicated element. 无需检查循环中的每个元素,您可以使用Set
对象删除每个重复的元素。
Note : I assume that the val
variable is an array. 注意 :我假设val
变量是一个数组。
addLanguage = (val) => [...new Set(val)];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.