使用扩展运算符更新非常深的对象
Posted
技术标签:
【中文标题】使用扩展运算符更新非常深的对象【英文标题】: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
【问题讨论】:
你能看看 redux 文档中的Normalizing State Shape 吗?我认为它会帮助你正常化你的状态并能够轻松地更新它! 它是标准化的,看看它在你的链接中给出的例子。 实际上,作为“结构化减速器”部分的作者,我认为“不可变更新模式”部分更相关:redux.js.org/docs/recipes/reducers/ImmutableUpdatePatterns.html 【参考方案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
和扩展运算符。
假设state
和children
中的appClassId
s 的数量在每个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]);
希望对你有帮助
【讨论】:
以上是关于使用扩展运算符更新非常深的对象的主要内容,如果未能解决你的问题,请参考以下文章