使用展开运算符更新非常深的对象



我有一个看起来像这样的对象:

  state: {
    "1": {
      "show": false,
      "description": "one",
      "children": {
        "1": { "show": false, "description": "one" },
        "2": { "show": false, "description": "one" }
      }
    },
    "2": {
      "show": false,
      "description": "one",
      "children": {
        "1": { "show": false, "description": "one" },
        "2": { "show": false, "description": "one" }
      }
    }
  }

我有一个 for 循环,可以将子"显示"属性更改为相反的布尔值。所以我尝试用这个更新值,但没有奏效。

      for (var childKey in state[appClassId].children) {
        newState = {
          ...state,
          [appClassId]: {
            children: {
              [childKey]: { ...state[appClassId].children[childKey], show: !state[appClassId].children[childKey].show}
            }
          }

"appClassId"变量是我从操作中获得的变量。

如何更新子属性中的每个键以用于实例状态.1.children.1.show

在@markerikson作者的帮助下:

http://redux.js.org/docs/recipes/reducers/ImmutableUpdatePatterns.html

我能够更新深层嵌套数据:

要更新的对象是此对象的"子"属性下的所有对象:

 state: {
    "1": {
      "show": false,
      "description": "one",
      "children": {
        "1": { "show": false, "description": "one" },
        "2": { "show": false, "description": "one" }
      }
    },
    "2": {
      "show": false,
      "description": "one",
      "children": {
        "1": { "show": false, "description": "one" },
        "2": { "show": false, "description": "one" }
      }
    }
  }

更新它的代码是:

let newState = {};
newState = { ...state, newState }
for (var childKey in newState[appClassId].children) {
  newState = {
    ...newState,
    [appClassId]: {
      ...newState[appClassId],
      children: {
        ...newState[appClassId].children,
        [childKey]: {
          ...newState[appClassId].children[childKey],
          show: !newState[appClassId].children[childKey].show
        }
      }
    }
  }
}

如果您正在做比分配一两个值更复杂的事情,除了扩展运算符之外,我还建议您依靠像lodash.js这样的实用程序库。

假设state内部的appClassId数和每个appClass内的children数是完全动态的:

import { reduce } from 'lodash'
const newState = reduce(state, (modifiedState, appClass, appClassId) => {
  const { children } = appClass
  // toggle show for each child (non-mutating)
  const toggledChildren = reduce(children, (newChildren, child, childId) => {
    return {
      ...newChildren,
      [childId]: { ...child, show: !child.show }
    }
  }, {})
  // persist modified children within the appClass
  return {
    ...modifiedState,
    [appClassId]: {
      ...appClass,
      children: toggledChildren
    }
  }
}, {})

希望这有帮助!

试试这个:

const originalChildren = state[appClassId].children;
let updatedChildren = {};
for (var child in originalChildren) {
   if (originalChildren.hasOwnProperty(child)) {
      updatedChildren = {
        ...updatedChildren,
        [child]: { ...originalChildren[child], show: !originalChildren[child].show }
      };
   }
}
const newState = {
  ...state,
  [appClassId]: {
    ...state[appClassId],
    children: { ...originalChildren, ...updatedChildren }
  }
}

另一个例子,

let test = [
  { id: 1, name: 'Phone',
    Devices: [
      { id: 1, name: 'BlackBerry',GroupId: 1 },
      { id: 2, name: 'Iphone', GroupId: 1 }
    ]
  }, { id: 2, name: 'Speaker',
    Devices: [
      { id: 3, name: 'Senheiser', GroupId: 2 },
      { id: 4, name: 'Simbadda', GroupId: 2 }
    ]
  }
];
const GroupId = 1;
const device = {
  id: 5,
  name: 'Android',
  GroupId: GroupId
}

let Group = [...test];
const idx = test.findIndex(payload => {
  return payload.id === GroupId
});
console.log(Group[idx].Devices = [...Group[idx].Devices, device]);

希望会有所帮助

最新更新