繁体   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