簡體   English   中英

這是使用 redux 刪除項目的正確方法嗎?

[英]Is this the correct way to delete an item using redux?

我知道我不應該改變輸入,應該克隆對象來改變它。 我遵循 redux starter 項目中使用的約定,該項目使用了:

ADD_ITEM: (state, action) => ({
  ...state,
  items: [...state.items, action.payload.value],
  lastUpdated: action.payload.date
})

添加項目 - 我使用 spread 將項目附加到數組中。

刪除我用過:

DELETE_ITEM: (state, action) => ({
  ...state,
  items: [...state.items.splice(0, action.payload), ...state.items.splice(1)],
  lastUpdated: Date.now() 
})

但這正在改變輸入狀態對象 - 即使我返回一個新對象,這是否被禁止?

不。永遠不要改變你的狀態。

即使您返回了一個新對象,您仍然在污染舊對象,這是您永遠不想做的。 這使得在舊狀態和新狀態之間進行比較時會出現問題。 例如,在 react-redux shouldComponentUpdate使用的shouldComponentUpdate中。 它還使時間旅行變得不可能(即撤消和重做)。

相反,使用不可變的方法。 始終使用Array#slice而永遠不要使用Array#splice

我從你的代碼中假設action.payload是被刪除項目的索引。 更好的方法如下:

items: [
    ...state.items.slice(0, action.payload),
    ...state.items.slice(action.payload + 1)
],

您可以使用數組過濾器方法從數組中刪除特定元素而不改變原始狀態。

return state.filter(element => element !== action.payload);

在您的代碼上下文中,它看起來像這樣:

DELETE_ITEM: (state, action) => ({
  ...state,
  items: state.items.filter(item => item !== action.payload),
  lastUpdated: Date.now() 
})

ES6 Array.prototype.filter方法返回一個包含符合條件的項目的新數組。 因此,在原始問題的上下文中,這將是:

DELETE_ITEM: (state, action) => ({
  ...state,
  items: state.items.filter(item => action.payload !== item),
  lastUpdated: Date.now() 
})

帶有對象的數組的不可變“DELETED”reducer 的另一種變體:

const index = state.map(item => item.name).indexOf(action.name);
const stateTemp = [
  ...state.slice(0, index),
  ...state.slice(index + 1)
];
return stateTemp;

黃金法則是我們不返回突變狀態,而是返回一個新狀態。 根據操作的類型,您可能需要在遇到減速器時以各種形式更新狀態樹。

在這種情況下,我們試圖從狀態屬性中刪除一個項目。

這讓我們想到了 Redux 的不可變更新(或數據修改)模式的概念。 不變性是關鍵,因為我們從不想直接更改狀態樹中的值,而是始終根據舊值進行復制並返回新值。

以下是如何刪除嵌套對象的示例:

 // ducks/outfits (Parent) // types export const NAME = `@outfitsData`; export const REMOVE_FILTER = `${NAME}/REMOVE_FILTER`; // initialization const initialState = { isInitiallyLoaded: false, outfits: ['Outfit.1', 'Outfit.2'], filters: { brand: [], colour: [], }, error: '', }; // action creators export function removeFilter({ field, index }) { return { type: REMOVE_FILTER, field, index, }; } export default function reducer(state = initialState, action = {}) { sswitch (action.type) { case REMOVE_FILTER: return { ...state, filters: { ...state.filters, [action.field]: [...state.filters[action.field]] .filter((x, index) => index !== action.index) }, }; default: return state; } }

為了更好地理解這一點,請務必查看這篇文章: https : //medium.com/better-programming/deleting-an-item-in-a-nested-redux-state-3de0cb3943da

使用 redux 以不同方式刪除項目。

方法 1:在這種情況下使用createSlice ( .. )

const { id } = action.payload; // destruct id
removeCart: (state, action) =>{
                 let { id } = action.payload;
                 let arr = state.carts.filter(item => item.id !== parseInt(id))
                 state.carts = arr;
               }

方法 2:在這種情況下使用switch (... ), spread-operator

const { id } = action.payload; // destruct id

case actionTypes.DELETE_CART:  
     return {
        ...state,
        carts: state.carts.filter((item) => item.id !== payload)
      };

對於這兩種方法都初始化了這個狀態:

  initialState: {
      carts: ProductData, // in productData mocked somedata     
    }

暫無
暫無

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

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