[英]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
是頁面上顯示的項目列表, selectedItems
是selectedItems
了哪些項目的列表。 當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
我將收到X
( id )。
因此,過濾器功能需要取出具有特定 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.