我有一个使用数组对象的reducer。我想根据给定的索引更改嵌套数组的值。这段代码有效,但我似乎无法使用深度冻结让我的测试工作。我试图使用.map
来查看此处的redux示例http://redux.js.org/docs/basics/Reducers.html以查找没有运气的索引。有什么想法吗?
export default function myReducer(state = { toDisplay: [] }, action) {
const { type, groupIndex, itemIndex } = action;
const newObject = Object.assign({}, state);
switch (type) {
case actionTypes.TOGGLE_GROUP:
newObject.toDisplay[groupIndex].isSelected = newObject.toDisplay[groupIndex].isSelected ? false : 'selected';
return newObject;
case actionTypes.TOGGLE_ITEM:
newObject.toDisplay[groupIndex].values[itemIndex].isSelected = newObject.toDisplay[groupIndex].values[itemIndex].isSelected ? false : true;
return newObject;
default:
return state;
}
}
修改
对于看过有用的redux video之后好奇的人,我想出了这个:
export default function myReducer(state = { toDisplay: [] }, action) {
const { type, groupIndex, itemIndex } = action;
switch (type) {
case actionTypes.TOGGLE_GROUP:
return {
...state,
toDisplay: [
...state.toDisplay.slice(0, groupIndex),
{
...state.toDisplay[groupIndex],
isSelected: state.toDisplay[groupIndex].isSelected ? false : 'selected'
},
...state.toDisplay.slice(groupIndex + 1)
]
};
case actionTypes.TOGGLE_ITEM:
return {
...state,
toDisplay: [
...state.toDisplay.slice(0, groupIndex),
{
...state.toDisplay[groupIndex],
values: [
...state.toDisplay[groupIndex].values.slice(0, itemIndex),
{
...state.toDisplay[groupIndex].values[itemIndex],
isSelected: state.toDisplay[groupIndex].values[itemIndex].isSelected ? false : true
},
...state.toDisplay[groupIndex].values.slice(itemIndex + 1)
]
},
...state.toDisplay.slice(groupIndex + 1)
]
};
default:
return state;
}
}
使用像建议的帮助器/库可能是最好的路线,但我的团队希望不添加另一个依赖项。
答案 0 :(得分:1)
首先,Object.assign(...)
只执行浅拷贝。请参阅here。
由于嵌套在嵌套在对象内的数组中的对象,我强烈推荐immutability helpers作出反应(如Rafael所述)。这些允许你做这样的事情:
case actionTypes.TOGGLE_GROUP:
return update(state, {
toDisplay: {
[groupIndex]: {
isSelected: {$set: newObject.toDisplay[groupIndex].isSelected ? false : 'selected'}
}
}
});
如果您希望使用原始js修改数组中的简单值,那么您可以使用以下内容:
return list
.slice(0,index)
.concat([list[index] + 1])
.concat(list.slice(index + 1));
(source)