redux - React-redux 嵌套状态,使用嵌套数组
问题描述
我正在尝试使用具有 redux 状态的多级嵌套数组,并且遇到了复杂性(或理解 :))问题。我刚刚开始学习 react(使用 redux),并认为我把它弄得太复杂了,并且没有正确地对状态进行建模。
(使用 Azure)我的状态看起来像这样
有很多租户。每个租户可以有 1 个或多个订阅。每个订阅可以有 1 个或多个资源组。每个资源组可以有 1 个或多个资源。每个资源可以有 1 个或多个标签。
看起来像这样:
tenants: [
{
DisplayName: "blah",
DomainName: "blah.onmicrosoft.com",
TenantId: "72f988bf-1111-1111-1111-111111111111",
active: false,
subs: []
},
{
DisplayName: "blah2",
DomainName: "blah2.onmicrosoft.com",
TenantId: "57aa6e76-1111-1111-1111-111111111111",
active: true,
subs: [
{
subId: '444-555',
subName: 'SubName',
state: "enabled",
active: true,
resourceGroups: [
{
name:"one",
id: "/blah/123/456",
resources: [
{
name: "vm1",
type: "Microsoft.Compute/VirtualMachine"
},
{
name: "vm2",
type: "Microsoft.Compute/VirtualMachine"
}
]
},
{
name:"two",
id: "/blah/555/222",
resources: [
{
name: "vm3",
type: "Microsoft.Compute/VirtualMachine"
},
{
name: "vm4",
type: "Microsoft.Compute/VirtualMachine"
}
]
},
]
}
]
}
]
}
我正在努力了解如何跟踪和修改每个项目的状态,例如在 UI 上显示/不显示、按钮单击等。因此,例如,如果我想要一个嵌套菜单,跟踪什么是什么,什么不是根据单击的内容等正确显示和反映以折叠或展开给定菜单。因此,例如,如果我单击“租户”按钮/框/标题,它会折叠所有子项。
我是否为每个状态“深度级别”创建一个函数,并传递索引?因此,例如,如果我想使用 VM 和标签,我会传递租户索引、子索引、RG 索引等?我认为这会奏效,但听起来很糟糕。
或者我是否以某种方式将状态拆分为多个减速器,也许一个用于租户,一个用于潜艇等?并且做一些作为状态属性的键引用,例如在resourceGroup reducer 中,有一个指向订阅索引的“子”键?
关于如何解决这个问题的任何建议或想法都会很棒。谢谢你。
编辑:我想我会更新我最终做的事情。
- 标准化了状态模型,所以每个资源都有相同的字段
- 'Normalized'/扁平化状态,所以它只包含一个数组
状态现在看起来像这样:
resources: [
{
type: "tenant",
displayName: "Microsoft",
shortId: "72f988bf-1111-1111-1111-111111111111",
longId: "/blah/123/456/789",
isVisible: false,
info: {
active: false,
domainName: "microsoft.onmicrosoft.com",
},
children: []
},
{
type: "tenant",
displayName: "blahdy blah blah",
shortId: "57aa6e76-1111-1111-1111-111111111111",
longId: "/blah/123/456",
isVisible: false,
info: {
active: true,
domainName: "blah.onmicrosoft.com",
},
children: [2, 7]
},
{
type: "subscription",
shortId: '444-55522',
longId: "/blah/123/456/789",
displayName: 'SubName',
isVisible: false,
info: {
active: true,
state: "enabled",
},
children: [3,4]
}
]
每个属性的 'children' 数组是对索引的引用,该索引是它的“嵌套”子级。
从这里开始,我现在能够递归渲染组件,有条件地检查子组件,如果是,则映射到递归渲染。
注意:要递归渲染从 redux 获取状态映射的组件,您必须先定义一个 const,导出该 const,然后在递归调用中使用该 const:
var ResourceWrapper = connect(mapStateToProps, mapDispatchToProps)(Resource);
export default ResourceWrapper;
解决方案
或者我是否以某种方式将状态拆分为多个减速器,也许一个用于租户,一个用于潜艇等?
当然,您需要将状态拆分为多个减速器(即单一责任原则)
将商店想象成一棵文档树。您可以将整棵树分成更小的树,从而使子问题在某种程度上被隔离。
所以基本上你有tenants/subs/resourceGroups/resources
树结构和目录结构。您的操作格式还应与目录结构匹配(即tenants/subs/add
添加订阅到某个租户或tenants/remove
删除租户)。拥有这种格式将有助于使用redux-dev-tools
.
因此,每个文件夹都有自己的减速器,就像tenants
它只是处理商店的“租户切片”一样。对于租户缩减器,它可以处理将影响租户切片的租户相关 UI 操作。
PS,具有类似于 API 响应的状态结构是一个优势(从某种意义上说,不再需要转换)。