簡體   English   中英

在反應中從狀態數組中刪除項目

[英]Deleting item from state array in react

我有一個像這樣的刪除函數:

   this.deleteItem = item => event => {
      const { res, selectedItems } = this.state;
      res.splice(res.indexOf(item), 1);
      selectedItems.splice(res.indexOf(item), 1);

      this.setState({
        res
      });
    };

這里, res是頁面上顯示的項目列表, selectedItemsselectedItems了哪些項目的列表。 res的項目被刪除時,應更新selectedItems以從列表中刪除該項目的索引。

但是,每當我嘗試刪除特定項目時,它只會刪除添加到數組中的最后一個項目,而不是與單擊的目標索引對應的項目。 索引的方式一定有問題,但我一直無法確定來源。

我也嘗試過參考here ,但這不起作用,因為我需要將item作為參數。

什么是解決這個問題的好方法?

非常感謝。

編輯:將函數更改為看起來像@HMK 的響應。 刪除項目后,render 方法中console.log(res)的輸出是一個對象數組,其形式如下:

res 
(9) […]
​
0: Object { id: 0, name: "a", description: "description of a", … }
​
1: Object { id: 2, name: "b", description: "description of b", … }
​
2: Object { id: 3, name: "c", description: "description of c", … }
​
3: Object { id: 4, name: "d", description: "description of d", … }
​
4: Object { id: 5, name: "e", description: "description of e", … }
​
5: Object { id: 6, name: "f", description: "description of f", … }
​
6: Object { id: 7, name: "g", description: "description of g", … }
​
7: Object { id: 8, name: "h", description: "description of h", … }
​
8: Object { id: 9, name: "i", description: "description of i", … }
​
length: 9
​
<prototype>: Array []

console.log(JSON.stringify(item,undefined,2)); deleteItem函數中是從數組中刪除的對象。

例如:

{
  "id": 10,
  "name": "j",
  "description": "description of j",
  "icon": "jIcon",
  "selected": false
}

當頁面上的所有項目都被選中時, console.log("selecteditems:", JSON.stringify(selectedItems))

selecteditems: [0,1,2,3,4,5,6,7,8,9,10]

要從數組中取出一個項目,您可以執行以下操作:

array.filter(item=>item!==itemToRemove)

所以在你的例子中:

this.deleteItem = item => event => {
  const filter = getter => val => getter(val) !== item.id
  this.setState({
    res: this.state.res.filter(filter(({id})=>id)),
    selectedItems: this.state.selectedItems.filter(
      filter(id=>id)
    )
  })
}

您遇到的問題是 res 存儲具有 id 的對象數組(例如: [{id:1}] ,然后 selectedItems 是存儲 id 的數組:(例如:[1])。

Array.prototype.filter 的工作方式如下: newArray = array.filter(filterFunction) 對於數組 filterFunction 中的每個項目,都會使用該項目調用。 如果 filterFunction 返回false則該項目不會被復制到newArray ,它返回 true 它被復制到 newArray 。 原始數組保持不變(因為它應該帶有狀態,因為你不應該改變它)。

所以問題是你的過濾器函數獲取數組的一個項目,決定它是否應該返回 true 或 false(true 保留該項目,false 不保留它)。 因此,如果我過濾res過濾器函數將收到{id:X} (帶有 id 的對象),但是當我過濾selectedItems我將收到Xid )。

因此,過濾器功能需要取出具有特定 id 的元素; res表示 id 是一個對象的屬性,而selectedItems它是一個 id。 對於res您可以編寫一個 getter 函數來從對象中獲取 id: resItem=>resItem.id ,從res為該函數提供一個項目,它將返回一個 id。 對於selectedItems ,getter 函數應該只返回它給定的值,因為selectedItems中的項目id,因此 getter 函數看起來像id=>id

好的,讓我們回到過濾器,我有一個名為selectedItems [9] 的 id 數組,想要刪除值為 9 的 id,讓我們調用 idToRemove 以便我可以這樣做: selectedItems.filter(id=>id!==idToRemove) 相同的函數不適用於res因為{id:9}永遠不等於9

但是如果我將一個選擇器傳遞給過濾器函數,這里會變得有點復雜,因為函數可以返回一個函數:

 const idToRemove = 9; //filter function return true for array item to stay in the copied array // and false to not include the array item in the copy const filter = getter => arrayItem => getter(arrayItem) !== idToRemove; //passing filter a getter function will return a function that takes // an item and uses the getter function on that item to compare it // to idToRemove const compareId = filter(id => id); console.log('keep 9?', compareId(9)); console.log('keep 8?', compareId(8)); //now create a filter function that takes an object and uses // the getter to get object.id and compares that to idToRemove const compareObjectWithId = filter(object => object.id); console.log('keep {id:9}?', compareObjectWithId({ id: 9 })); console.log('keep {id:8}?', compareObjectWithId({ id: 8 }));

所以compareId是一個函數,我們可以用來從selectedItems過濾出一個項目, compareObjectWithId是一個我們可以用來從res過濾出一個項目的函數,這里是過濾器的使用方式:

 const idToRemove = 9; const createFilterFunction = getter => arrayItem => getter(arrayItem) !== idToRemove; console.log( '[2,9] remove id 9', [2, 9].filter(createFilterFunction(id => id)) ); console.log( '[{id:2},{id:9}] remove id 9', [{ id: 2 }, { id: 9 }].filter( createFilterFunction(object => object.id) ) );

為了完成,我將添加現代代碼來從對象中刪除一個鍵(不要在堆棧溢出代碼片段上嘗試這個,因為它使用的是古老的 babel 版本)

const org = {a:1,b:2};
const withoutA = Object.fromEntries(
  Object.entries(org).filter(([key])=>key!=='a')//removed key 'a'
)

暫無
暫無

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

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