I have a immutable nested tree (mori, immutable-js et al) consisting of arbitrary nodes, think file browser. The tree gets rendered by React. If a component representing a node receives focus, I'd like to:
- Show an input field on the node component to change e.g. the node name.
- Show a global panel that contains UI components to edit additional properties of the currently focused node, depending on the type of the selected node.
A simplistic state object could look like this:
{
root: {
type: 'folder'
name: 'Root',
focused: false,
children: [
{
type: 'text',
name: 'Essay',
focused: false
},
{
type: 'folder',
name: 'Images',
focused: false,
children: [
{
type: 'image',
name: 'Paris',
focused: true
}
]
}
]
},
currentlyFocusedNode: <Reference to Paris node>
}
Now, how would I keep a valid reference to the currently focused node? If I stored a Paris node reference at currentlyFocusedNode
, it would be out of sync as soon as any other part of the app modifies the node (e.g. the inline name input from above). I thought about storing the path to the focused node, which I could use to retrieve the current reference:
currentlyFocusedNode: ['root', 'children', 0, 'children', 0]
But this seems very shaky to me as well, because even a simple node move operation on the tree could leave this path pointing to the wrong or even a non-existing node.
How are those kind of things handled with immutable data structures? Or am I not thinking "immutable" enough at all?