我有一个带有一些redux状态的反应应用程序,如下所示:
{
shape1: {
constraints: {
constraint1: {
key: value
},
constraint2: {
key: value
}
}
},
shape2: {
constraints: {
constraint1: {
key: value
},
constraint2: {
key: value
}
}
}
}
我发送一个动作,想要删除一个约束对象,即。 shape1的constraint1。这是我的reducer对于这个动作的样子,比如说我试图从shape1中删除constraint1:
case DELETE_CONSTRAINT:
shape = action.payload; // ie. shape1, the parent of the constraint I
// am trying to delete
let {
[shape]: {'constraints':
{'constraint1': deletedItem}
}, ...newState
} = state;
return newState;
这将从状态中移除整个shape1对象,而不仅仅是单个constraint1对象。我出错的地方/这样做的最佳方法是什么?我更喜欢使用对象休息,以便与我的其余代码保持一致。
感谢。
答案 0 :(得分:2)
在解构中使用rest语法来获取对象的切片时,您将获得相同“级别”的所有其他内容。
let {
[shape]: {'constraints':
{'constraint1': deletedItem}
}, ...newState
} = state;
在这种情况下,newState除了[shape]
之外还包含其他所有内容。
由于您的州有多个嵌套级别,您必须使用解构和休息语法提取新约束,然后创建一个新状态。
const state = {
shape1: {
constraints: {
constraint1: {
key: 'value'
},
constraint2: {
key: 'value'
}
}
},
shape2: {
constraints: {
constraint1: {
key: 'value'
},
constraint2: {
key: 'value'
}
}
}
};
const shape = 'shape1';
const constraint = 'constraint1';
// extract constraints
const {
[shape]: {
constraints: {
[constraint]: remove,
...constraints
}
}
} = state;
// create the next state
const newState = {
...state,
[shape]: {
...state[shape], // if shape contains only constraints, you keep skip this
constraints
}
}
console.log(newState);
答案 1 :(得分:0)
简而言之,不是没有对象 - 不是使用扩展运算符。
您可以通过其他方式执行此操作,但不会改变您的状态,例如过滤器,例如:
return state.filter((element, key) => key !== action.payload);
作为旁注 - 方法和风格的一致性与实际代码的一致性之间存在巨大差异。如果以不同的方式做出更合乎逻辑的意义,那就不要觉得需要鞋拔一些东西以保持一致性。如果它真正打破了其他开发人员正在处理的应用程序的一致性,请记录它的不同之处。