反应推送数组中的唯一对象

时间:2017-07-11 08:35:24

标签: javascript reactjs

我有一个应该向数组中添加唯一元素的函数:

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])
        }
    }
}

论证&#39; val&#39;每次获取一个带有附加元素的数组(我在UI上有一个多选框,我从中添加语言),这就是为什么在If循环中我试图检查我的语言数组是否已经具有该特定元素。但是这没有效果,最后我的语言数组包含相同的元素,即在后续调用中将相同的元素添加两次或三次等。

['German']
['German', 'German', 'Arabic']
...

我做错了什么?

3 个答案:

答案 0 :(得分:3)

您正在寻找数组中false的索引。那是因为,indexOf(val[i].id === -1)将始终检查indexOf(false),即-1。所以你重新添加每种语言。

您可能正在使用与此类似的算法:

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. 
}

请注意,您应始终使用setState来改变状态。

答案 1 :(得分:2)

您的代码存在一些问题:

  • 首先,永远不会直接改变this.state。这是反模式 并可能产生不希望的结果。请改用this.setState()

  • 无需在循环中执行indexOfindexOf将迭代数组并返回搜索项的索引,如果它不在数组中,则返回-1

  • 您必须为this.state.createNewDeliveryData数组的languages对象创建副本。

那说,一个解决方案可能是:

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
  }
}

或以更紧凑的形式:

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
  }
}

答案 2 :(得分:1)

您可以使用if(!empty($results )){ $json['success'] = true; $json['filters'] = $results; } else { $json['success'] = false; } 对象删除每个重复的元素,而不是检查循环中的每个元素。

注意:我假设Set变量是一个数组。

val