在 redux 状态树中添加新数据
add new data inside redux state tree
我有一个带有嵌套节点树的应用程序。所有节点都是同一类型。
{
id: 1,
title: "node_1",
children: [
{
id: 2,
title: "node_2",
children: []
},
{
id: 3,
title: "node_3",
children: []
}
]
}
当用户扩展某些节点(例如 id === 3 的节点)时,我必须对数据库执行请求并在节点的 "children" 属性 内插入响应(子数组)编号 === 3 。所以结果应用程序状态应该是这样的:
{
id: 1,
title: "node_1",
children: [
{
id: 2,
title: "node_2",
children: []
},
{
id: 3,
title: "node_3",
children: [
{
id: 4,
title: "node_4",
children: []
},
{
id: 5,
title: "node_5",
children: []
}
]
}
]
}
如何将子数组粘贴到 node_3 子 属性 中?
只需遍历 children
数组并推送到更正一个 .
var id = expandedItemId;
for(var i = 0; i < obj.children.length; i++){
if(obj.id == expandedItemId){
obj.children.push(`data got from server`);
}
}
对于 Redux 存储中的关系或规范化数据,建议的方法是以 "normalized" 方式组织它,类似于数据库表。这将使管理更新变得更加容易。参见 http://redux.js.org/docs/FAQ.html#organizing-state-nested-data, , and https://github.com/reactjs/redux/pull/1269。
鉴于:
const layer1Id = 1;
const layer2Id = 3;
const newArray = [
{
id: 4,
title: "node_4",
children: [],
},
{
id: 5,
title: "node_5",
children: [],
}
];
然后,在减速器中你会做:
return Object.assign({}, state, { children: state.children.map(child => {
if (child.id !== layer1Id) return child;
return Object.assign({}, child, { children: child.children.map(node => {
if (node.id !== layer2Id) return node;
return Object.assign({}, node, { children: node.children.concat(newArray) });
})});
})});
确保您不会改变之前的状态。
如果它是动态或深度嵌套的,我会建议你写一些递归函数来代替它。
编辑:这是示例递归解决方案(未经测试)。 indices
按级别排序(即:indices[0]
表示一级id,indices[1]
表示二级id):
const state = { ... };
const indices = [1, 3, 4, 5, 6];
const newArray = [ ... ];
const recursion = (node, ids, newChildren) => {
let children;
if (ids.length === 0) {
children = newChildren;
} else {
children = node.children.map(child => {
if (child.id !== ids[0]) return child;
return Object.assign({}, child, { children: recursion(child, ids.slice(1), newChildren) });
});
}
return Object.assign({}, node, { children });
};
recursion(state, indecies, newArray);
我有一个带有嵌套节点树的应用程序。所有节点都是同一类型。
{
id: 1,
title: "node_1",
children: [
{
id: 2,
title: "node_2",
children: []
},
{
id: 3,
title: "node_3",
children: []
}
]
}
当用户扩展某些节点(例如 id === 3 的节点)时,我必须对数据库执行请求并在节点的 "children" 属性 内插入响应(子数组)编号 === 3 。所以结果应用程序状态应该是这样的:
{
id: 1,
title: "node_1",
children: [
{
id: 2,
title: "node_2",
children: []
},
{
id: 3,
title: "node_3",
children: [
{
id: 4,
title: "node_4",
children: []
},
{
id: 5,
title: "node_5",
children: []
}
]
}
]
}
如何将子数组粘贴到 node_3 子 属性 中?
只需遍历 children
数组并推送到更正一个 .
var id = expandedItemId;
for(var i = 0; i < obj.children.length; i++){
if(obj.id == expandedItemId){
obj.children.push(`data got from server`);
}
}
对于 Redux 存储中的关系或规范化数据,建议的方法是以 "normalized" 方式组织它,类似于数据库表。这将使管理更新变得更加容易。参见 http://redux.js.org/docs/FAQ.html#organizing-state-nested-data,
鉴于:
const layer1Id = 1;
const layer2Id = 3;
const newArray = [
{
id: 4,
title: "node_4",
children: [],
},
{
id: 5,
title: "node_5",
children: [],
}
];
然后,在减速器中你会做:
return Object.assign({}, state, { children: state.children.map(child => {
if (child.id !== layer1Id) return child;
return Object.assign({}, child, { children: child.children.map(node => {
if (node.id !== layer2Id) return node;
return Object.assign({}, node, { children: node.children.concat(newArray) });
})});
})});
确保您不会改变之前的状态。 如果它是动态或深度嵌套的,我会建议你写一些递归函数来代替它。
编辑:这是示例递归解决方案(未经测试)。 indices
按级别排序(即:indices[0]
表示一级id,indices[1]
表示二级id):
const state = { ... };
const indices = [1, 3, 4, 5, 6];
const newArray = [ ... ];
const recursion = (node, ids, newChildren) => {
let children;
if (ids.length === 0) {
children = newChildren;
} else {
children = node.children.map(child => {
if (child.id !== ids[0]) return child;
return Object.assign({}, child, { children: recursion(child, ids.slice(1), newChildren) });
});
}
return Object.assign({}, node, { children });
};
recursion(state, indecies, newArray);