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

新手上路,请多包涵

我知道我不应该改变输入,应该克隆对象来改变它。我遵循了 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()
})

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

原文由 CWright 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 300
2 个回答

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

即使您正在返回一个新对象,您仍然会污染旧对象,这是您永远不想做的。这使得在旧状态和新状态之间进行比较时出现问题。例如在 shouldComponentUpdate 中,react-redux 在后台使用。它还使时间旅行变得不可能(即撤消和重做)。

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

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

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

原文由 David L. Walsh 发布,翻译遵循 CC BY-SA 3.0 许可协议

您可以使用数组过滤器方法从数组中删除特定元素而不改变原始状态。

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

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

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

原文由 Steph M 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题