【问题标题】:Update very deep object with spread operator使用扩展运算符更新非常深的对象
【发布时间】:2017-06-13 12:48:46
【问题描述】:

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

  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”变量是我从操作中获得的变量。

如何更新子属性中的每个键,例如 state.1.children.1.show

【问题讨论】:

标签: javascript reactjs redux react-redux spread-syntax


【解决方案1】:

在@markerikson 作者的帮助下:

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

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

要更新的对象是该对象的“children”属性下的所有对象:

 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
        }
      }
    }
  }
}

【讨论】:

    【解决方案2】:

    如果您做的事情比分配一个或两个值更复杂,我建议您使用 a utility library like lodash.js 和扩展运算符。

    假设statechildren 中的appClassIds 的数量在每个appClass 中是完全动态的:

    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
        }
      }
    }, {})
    

    希望这会有所帮助!

    【讨论】:

      【解决方案3】:

      试试这个:

      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 }
        }
      }
      

      【讨论】:

        【解决方案4】:

        另一个例子,

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

        希望对你有帮助

        【讨论】:

          猜你喜欢
          • 2018-09-04
          • 2021-12-28
          • 2017-06-12
          • 2017-11-15
          • 1970-01-01
          • 1970-01-01
          • 2017-12-07
          • 2021-04-09
          相关资源
          最近更新 更多