Javascript 这是使用 redux 删除项目的正确方法吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34582678/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is this the correct way to delete an item using redux?
提问by CWright
I know I'm not supposed to mutate the input and should clone the object to mutate it. I was following the convention used on a redux starter project which used:
我知道我不应该改变输入,应该克隆对象来改变它。我遵循 redux starter 项目中使用的约定,该项目使用了:
ADD_ITEM: (state, action) => ({
...state,
items: [...state.items, action.payload.value],
lastUpdated: action.payload.date
})
for adding an item - I get the use of spread to append the item in the array.
添加项目 - 我使用 spread 将项目附加到数组中。
for deleting I used:
删除我用过:
DELETE_ITEM: (state, action) => ({
...state,
items: [...state.items.splice(0, action.payload), ...state.items.splice(1)],
lastUpdated: Date.now()
})
but this is mutating the input state object - is this forbidden even though I am returning a new object?
但这正在改变输入状态对象 - 即使我返回一个新对象,这是否被禁止?
回答by David L. Walsh
No. Never mutate your state.
不。永远不要改变你的状态。
Even though you're returning a new object, you're still polluting the old object, which you never want to do. This makes it problematic when doing comparisons between the old and the new state. For instance in shouldComponentUpdate
which react-redux uses under the hood. It also makes time travel impossible (i.e. undo and redo).
即使您返回了一个新对象,您仍然在污染旧对象,这是您永远不想做的。这使得在旧状态和新状态之间进行比较时会出现问题。例如shouldComponentUpdate
,react-redux 在幕后使用。它还使时间旅行变得不可能(即撤消和重做)。
Instead, use immutable methods. Always use Array#slice
and never Array#splice
.
相反,使用不可变的方法。始终使用Array#slice
,从不使用Array#splice
。
I assume from your code that action.payload
is the index of the item being removed. A better way would be as follows:
我从您的代码中假设这action.payload
是要删除的项目的索引。更好的方法如下:
items: [
...state.items.slice(0, action.payload),
...state.items.slice(action.payload + 1)
],
回答by Steph M
You can use the array filter method to remove a specific element from an array without mutating the original state.
您可以使用数组过滤器方法从数组中删除特定元素而不改变原始状态。
return state.filter(element => element !== action.payload);
In the context of your code, it would look something like this:
在您的代码上下文中,它看起来像这样:
DELETE_ITEM: (state, action) => ({
...state,
items: state.items.filter(item => item !== action.payload),
lastUpdated: Date.now()
})
回答by JoeTidee
The ES6 Array.prototype.filter
method returns a new array with the items that match the criteria. Therefore, in the context of the original question, this would be:
ES6Array.prototype.filter
方法返回一个包含符合条件的项目的新数组。因此,在原始问题的上下文中,这将是:
DELETE_ITEM: (state, action) => ({
...state,
items: state.items.filter(item => action.payload !== item),
lastUpdated: Date.now()
})
回答by Roman
Another one variation of the immutable "DELETED" reducer for the array with objects:
带有对象的数组的不可变“DELETED”reducer 的另一种变体:
const index = state.map(item => item.name).indexOf(action.name);
const stateTemp = [
...state.slice(0, index),
...state.slice(index + 1)
];
return stateTemp;
回答by Kasra Khosravi
The golden rule is that we do not return a mutated state, but rather a new state. Depending on the type of your action, you might need to update your state tree in various forms when it hits the reducer.
黄金法则是我们不返回一个变异的状态,而是一个新的状态。根据操作的类型,您可能需要在遇到减速器时以各种形式更新状态树。
In this scenario we are trying to remove an item from a state property.
在这种情况下,我们试图从状态属性中删除一个项目。
This brings us to the concept of Redux's immutable update (or data modification) patterns. Immutability is key because we never want to directly change a value in the state tree, but rather always make a copy and return a new value based on the old value.
这让我们想到了 Redux 的不可变更新(或数据修改)模式的概念。不变性是关键,因为我们从不想直接更改状态树中的值,而是始终根据旧值进行复制并返回新值。
Here is an example of how to delete a nested object:
以下是如何删除嵌套对象的示例:
// 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;
}
}
To understand this better, make sure to check out this article: https://medium.com/better-programming/deleting-an-item-in-a-nested-redux-state-3de0cb3943da
为了更好地理解这一点,请务必查看这篇文章:https: //medium.com/better-programming/deleting-an-item-in-a-nested-redux-state-3de0cb3943da