传播省略不会省略操作处理程序中的属性



我觉得我快疯了,下面的代码在reducer中使用时不起作用,但在控制台或操场上使用完全相同的变量运行它绝对完美。

[MutationTypes.DELETE_GOALS_SUCCESS]: (state, { payload }) => {
//payload is {deleted_goals: [1, 2, 3]}, goals is {1: {...}, 2: {...}, ... n: {...}}
const goals = { ...state.goals };
const newGoals = payload.deleted_goals.reduce((acc, id) => {
const { [id]: omitted, ...newAcc } = acc; //newAcc still contains "id" key
console.log(
"After spread",
"New goals:",
newAcc,
"Old goals:",
acc, //acc and newAcc are the same aside from different pointers
"Removed goal",
omitted,
);
return newAcc;
}, goals);
return {
...state,
goals: newGoals,
};
},

const { [id]: omitted, ...newAcc } = acc;部分就是没有按预期工作。由于某种原因,newAcc仍然包含id密钥,因此每次迭代都保持不变。id键包含在目标对象中,我可以记录omitted对象。正如我所说,我可以用完全相同的变量在其他任何地方运行完全相同的代码行,它将完美工作。这可能是redux或我的reducer实现的问题,但我无法想象什么是错误的,以及它如何会导致这样的后果。State只是普通对象,State.goal也是普通对象,我甚至在做它的浅层复制。我可以JSON.stringify它们,复制粘贴到其他地方,然后省略我在这里做的相同方式,它就会工作。你知道是什么导致了这种奇怪的互动吗?有多种方法可以在不扩散的情况下做到这一点,比如使用删除运算符,或者从头开始构建新对象,但我想知道为什么对象会对扩散破坏"免疫"。

我已经尝试在操作处理程序和reduce回调中省略了对新鲜对象的扩展,它成功了,看起来这个特定对象(state.goals(有一些东西。然而,它只是一个类似映射的对象,其结构如下:{id1: {goalwithid}, id2:{goalwithid2} ...}id1、id2等都是数字。

刚刚尝试了深度克隆对象(用const goals = _.cloneDeep(state.goals)替换了const goals = { ...state.goals };,但没有任何变化。

为什么不这么做:

[MutationTypes.DELETE_GOALS_SUCCESS]: (state, { payload }) => {
//payload is {deleted_goals: [1, 2, 3]}, goals is {1: {...}, 2: {...}, ... n: {...}}
const goals = state.goals;
const newGoals = Object.keys(goals).reduce((acc, key) => {
if(payload.deleted_goals.includes(parseInt(key))) {
return acc;
} else {
return (acc[key] = goals[key], acc);
}
}, {})
return {
...state,
goals: newGoals,
};
},

相关内容

最新更新