在 redux 状态树中添加新数据
Posted
技术标签:
【中文标题】在 redux 状态树中添加新数据【英文标题】:add new data inside redux state tree 【发布时间】:2016-09-29 22:44:39 【问题描述】:我有一个带有嵌套节点树的应用程序。所有节点都是同一类型。
id: 1,
title: "node_1",
children: [
id: 2,
title: "node_2",
children: []
,
id: 3,
title: "node_3",
children: []
]
当用户扩展某个节点(例如 id === 3 的节点)时,我必须向数据库执行请求并在 id === 3 的节点的“children”属性内插入响应(数组子级)。所以结果应用程序状态应该是这样的:
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 子属性中粘贴子数组?
【问题讨论】:
我强烈推荐查看这个 redux 树示例 github.com/reactjs/redux/tree/master/examples/tree-view 【参考方案1】:给定:
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);
【讨论】:
是的,它会嵌套很深。你能附上一些可以匹配这种情况的递归函数的链接吗? 请给我一些时间。 @PavelPoberezhnyi 我添加了递归解决方案。 很抱歉,但无法理解什么是索引和 ids.slice(1) @PavelPoberezhnyiindicies
是id
的列表,因此[1, 2, 3]
将使state.children[/* child with id = 1 */].children[/* child with id = 2 */].children[/* child with id = 3 */]
得到修改。 slice(1)
返回不带第一个元素的 indicies
。这是递归函数的一般结构。如果你不熟悉递归的概念,你可以看一些像here 这样的例子。从本质上讲,您在达到某些基本情况的同时不断将相同的功能应用于自身。【参考方案2】:
Redux 存储中的关系或规范化数据的建议方法是以“规范化”方式组织它,类似于数据库表。这将使管理更新更容易。请参阅http://redux.js.org/docs/FAQ.html#organizing-state-nested-data、How to handle tree-shaped entities in Redux reducers? 和 https://github.com/reactjs/redux/pull/1269。
【讨论】:
【参考方案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`);
【讨论】:
返回数组的新实例不是最佳做法吗? 对不起@ctrlplusb 没有明白你的意思。你能澄清一下吗? @ctrlplusb 是的。所以它应该是obj.children.concat('data got from server')
之类的东西,而不是在 if 语句中。
很抱歉,这可能是 3-d 或 4-th 级别。所以,如下所述,我必须编写一些递归函数以上是关于在 redux 状态树中添加新数据的主要内容,如果未能解决你的问题,请参考以下文章