Answers:
如何使用解构赋值语法?
const original = {
foo: 'bar',
stack: 'overflow',
};
// If the name of the property to remove is constant
const { stack, ...withoutFirst } = original;
console.log(withoutFirst); // Will be { "foo": "bar" }
// If the name of the property to remove is from a variable
const key = 'stack'
const { [key]: value, ...withoutSecond } = original;
console.log(withoutSecond); // Will be { "foo": "bar" }
// To do a deep removal with property names from variables
const deep = {
foo: 'bar',
c: {
x: 1,
y: 2
}
};
const parentKey = 'c';
const childKey = 'y';
// Remove the 'c' element from original
const { [parentKey]: parentValue, ...noChild } = deep;
// Remove the 'y' from the 'c' element
const { [childKey]: removedValue, ...childWithout } = parentValue;
// Merge back together
const withoutThird = { ...noChild, [parentKey]: childWithout };
console.log(withoutThird); // Will be { "foo": "bar", "c": { "x": 1 } }
const deleteProperty = ({[key]: _, ...newObj}, key) => newObj;
。用法:deleteProperty({a:1, b:2}, "a");
给{b:2}
deep['c']
为空,则深度删除示例将崩溃,因此在一般情况下,您可能需要添加对密钥是否存在的检查。
我觉得ES5阵列的方法,如filter
,map
和reduce
有用的,因为他们总是返回新的数组或对象。在这种情况下,我将Object.keys
遍历对象,然后Array#reduce
将其变回对象。
return Object.assign({}, state, {
c: Object.keys(state.c).reduce((result, key) => {
if (key !== 'y') {
result[key] = state.c[key];
}
return result;
}, {})
});
myObject
密钥myKey
后获得的副本:Object.keys(myObject).reduce((acc, cur) => cur === myKey ? acc : {...acc, [cur]: myObject[cur]}, {})
您可以_.omit(object, [paths])
从lodash库中使用
路径可以嵌套,例如: _.omit(object, ['key1.key2.key3'])
_.omit
无法删除深层属性(OP询问的内容)。有用omit-deep-lodash
于此目的的模块。
_.cloneDeep(obj)
lodash 对我们有用,也许更合适。这样可以轻松地复制对象,然后您可以简单地使用js delete obj.[key]
删除密钥。
只需使用ES6对象解构功能
const state = {
c: {
x: '42',
y: '43'
},
}
const { c: { y, ...c } } = state // generates a new 'c' without 'y'
console.log({...state, c }) // put the new c on a new state
const {y, ...c} = state.c
可能比c
左手有两个更清晰。
const name = 'c'
那么您可以这样做,const {[name]:deletedValue, ...newState} = state
然后返回newState
您的reducer。这是用于顶级密钥删除
那是因为您正在将的值复制state.c
到另一个对象。该值是指向另一个javascript对象的指针。因此,这两个指针都指向同一对象。
试试这个:
let newState = Object.assign({}, state);
console.log(newState == state); // false
console.log(newState.c == state.c); // true
newState.c = Object.assign({}, state.c);
console.log(newState.c == state.c); // now it is false
delete newState.c.y;
您还可以对对象进行深度复制。看到这个问题,您会发现最适合您的。
state.c
是参考,并且可以很好地复制参考。Redux需要标准化的状态形状,这意味着在嵌套状态时使用id而不是引用。请查看redux文档:redux.js.org/docs/recipes/reducers/NormalizingStateShape.html
function dissoc(key, obj) {
let copy = Object.assign({}, obj)
delete copy[key]
return copy
}
另外,如果要寻找功能性的编程工具包,请查看Ramda。
您遇到的问题是您没有深入克隆初始状态。所以你有一个浅表。
您可以使用传播算子
const newState = { ...state, c: { ...state.c } };
delete newState.c.y
或遵循相同的代码
let newState = Object.assign({}, state, { c: Object.assign({}, state.c) });
delete newState.c.y
效用 ;))
const removeObjectField = (obj, field) => {
// delete filter[selectName]; -> this mutates.
const { [field]: remove, ...rest } = obj;
return rest;
}
动作类型
const MY_Y_REMOVE = 'MY_Y_REMOVE';
动作创造者
const myYRemoveAction = (c, y) => {
const result = removeObjectField(c, y);
return dispatch =>
dispatch({
type: MY_Y_REMOVE,
payload: result
})
}
减速器
export default (state ={}, action) => {
switch (action.type) {
case myActions.MY_Y_REMOVE || :
return { ...state, c: action.payload };
default:
return state;
}
};
Object.assign
仅创建的浅表副本,state
因此state.c
并且newState.c
将指向同一共享库。您试图y
从共享对象c
而不是新对象中删除属性newState
。