使用object rest删除嵌套对象

时间:2017-09-16 06:06:51

标签: reactjs ecmascript-6 redux ecmascript-next

我有一个带有一些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对象。我出错的地方/这样做的最佳方法是什么?我更喜欢使用对象休息,以便与我的其余代码保持一致。

感谢。

2 个答案:

答案 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);

一致性旁注

作为旁注 - 方法和风格的一致性与实际代码的一致性之间存在巨大差异。如果以不同的方式做出更合乎逻辑的意义,那就不要觉得需要鞋拔一些东西以保持一致性。如果它真正打破了其他开发人员正在处理的应用程序的一致性,请记录它的不同之处。