首页 文章

这是使用redux删除项目的正确方法吗?

提问于
浏览
77

我知道我不应该改变输入,应该克隆对象来改变它 . 我遵循在redux启动项目中使用的约定,该项目使用:

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() 
})

但是这会改变输入状态对象 - 即使我返回一个新对象,这是否被禁止?

4 回答

  • 139

    具有对象的数组的不可变“DELETED”reducer的另一个变体:

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

    ES6 Array.prototype.filter 方法返回一个包含与条件匹配的项的新数组 . 因此,在原始问题的背景下,这将是:

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

    您可以使用数组筛选器方法从数组中删除特定元素,而不会改变原始状态 .

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

    在您的代码的上下文中,它看起来像这样:

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

    不,永远不要改变你的状态 .

    即使你仍然污染旧物体,你永远也不想这样做 . 这使得在旧状态和新状态之间进行比较时会出现问题 . 例如在 shouldComponentUpdate 中,react-redux在引擎盖下使用 . 它也使得时间旅行变得不可能(即撤消和重做) .

    相反,使用不可变的方法 . 始终使用 Array#slice 而不是 Array#splice .

    我假设您的代码中 action.payload 是要删除的项目的索引 . 更好的方法如下:

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

相关问题