使用对象 rest 删除嵌套对象

Using object rest to delete nested object

我有一个带有一些 redux 状态的 React 应用程序,如下所示:

{
    shape1: {
        constraints: {
            constraint1: {
                key: value
            },
            constraint2: {
                key: value
            }
        }
    }, 
    shape2: {
        constraints: {
            constraint1: {
                key: value
            },
            constraint2: {
                key: value
            }
        }            
    }
}

我调度了一个动作并想删除一个约束对象,即。形状 1 的约束 1。这是我的 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 对象。我哪里出错了/这样做的最佳方法是什么?为了与我的其余代码保持一致,我更愿意使用对象剩余。

谢谢。

简而言之,不,不是对象 - 不是扩展运算符。

不过,您可以在不改变状态的情况下通过其他方式进行操作,例如过滤器,例如:

return state.filter((element, key) => key !== action.payload);

一致性旁注

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

当在解构中使用剩余语法来获取对象的一部分时,您将在同一部分获得其他所有内容 "level"。

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