I'm trying to work with multiple levels of nested arrays with redux state and am running into complexity (or comprehension :)) issues. I've just started learning react (with redux) and think I am making this too complex and not modeling the state correctly.
(Working with Azure) my state looks like this
There is an array of tenants. Each tenant can have 1 or more subscriptions. Each subscription can have 1 or more resource-groups. Each resource-group can have 1 or more resources. Each resource can have 1 or more tags.
Looks something like this:
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"
}
]
},
]
}
]
}
]
}
I'm struggling to get my head around how to track and modify state per item, for things like showing/not showing on the UI, button clicking etc. So for example if I want a nested menu, tracking what is and isn't showing and reflecting properly based on what's clicked etc. to collapse or expand a given menu. So for example if I click on the 'tenant' button/box/heading, it collapses all child items.
Do I make a function per state 'depth level', and pass around indexes? So for e.g. if I wanted to work with a VM and tags, I would pass tenant index, sub index, RG index etc? I think that would work but sounds terrible TBH.
Or do I somehow split the state into multiple reducers, perhaps one for tenants, one for subs etc? And do some for of key reference as a state property e.g. in a resourceGroup reducer, have a "sub" key which points to the subscription index?
Any advice or thoughts about how to tackle this would be great. Thank you.
edit: I thought I'd update what I ended up doing.
- Standardised the state model, so each resource has the same fields
- 'Normalized'/flattened the state, so it only consisted of a single array
The state now looks like this:
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]
}
]
The 'children' array for each property is a reference to the index which is it's 'nested' child.
From here, I am now able to recursively render a component, conditionally checking for children and if so, mapping into a recursive render.
Note: to recursively render a component which gets it's state mapped from redux, you have to define a const first, export that const, and use that const in your recursive call:
var ResourceWrapper = connect(mapStateToProps, mapDispatchToProps)(Resource);
export default ResourceWrapper;