簡體   English   中英

反應推送數組中的唯一對象

[英]react push unique objects in 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])
        }
    }
}

參數val每次都會得到一個帶有附加元素的數組(我從中添加語言的UI上有一個多選框),這就是為什么在If循環中我試圖檢查我的語言數組是否已經具有該特定元素。 但是,這沒有任何效果,最后,我的語言數組包含相同的元素,即在后續調用中將相同的元素添加兩次或三次。

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

我究竟做錯了什么?

您正在尋找數組中的false索引。 這是因為indexOf(val[i].id === -1)將始終檢查indexOf(false) 因此,您需要重新添加每種語言。

您可能正在尋找一種更類似於此的算法:

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更改react中的狀態。

您的代碼有一些問題:

  • 首先, 永遠 this.state直接this.state 這是反模式,可能會產生不希望的結果。 請改用this.setState()

  • 無需在循環中執行indexOf indexOf將迭代該數組並返回搜索到的項目的索引;如果它不在數組中,則返回-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
  }
}

無需檢查循環中的每個元素,您可以使用Set對象刪除每個重復的元素。

注意 :我假設val變量是一個數組。

addLanguage = (val) => [...new Set(val)];

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM