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

JavaScript

橙ぺo痕

2020-03-12

我知道我不应该改变输入,而应该克隆对象来改变它。我遵循在redux入门项目上使用的约定,该约定使用了:

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

用于添加项目-我使用了点差将项目追加到数组中。

用于删除我使用的:

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

但这改变了输入状态对象-即使我要返回一个新对象,这也是禁止的吗?

第958篇《这是使用Redux删除项目的正确方法吗?》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

4个回答
Near路易小胖 2020.03.12

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

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

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

DELETE_ITEM: (state, action) => ({
  ...state,
  items: state.items.filter(item => item !== action.payload),
  lastUpdated: Date.now() 
})
LEY古一阿飞 2020.03.12

ES6 Array.prototype.filter方法返回一个新数组,其中包含与条件匹配的项目。因此,在原始问题的范围内,这将是:

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

带有对象的数组的不可变“ DELETED”缩减器的另一种变体:

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

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

即使您要返回一个新对象,您仍然会污染旧对象,这是您永远都不想做的。这使得在旧状态和新状态之间进行比较时会出现问题。例如shouldComponentUpdate,react-redux在引擎盖下使用。这也使时间旅行成为不可能(即撤消和重做)。

而是使用不可变方法。永远使用Array#slice,永不Array#splice

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

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

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android