[英]How does one store “pointers” to nested nodes in an immutable tree in React/Javascript?
I have a immutable nested tree ( mori , immutable-js et al) consisting of arbitrary nodes, think file browser. 我有一个由任意节点组成的不可变嵌套树( mori , immutable-js等),想想文件浏览器。 The tree gets rendered by React. 树由React呈现。 If a component representing a node receives focus, I'd like to: 如果代表节点的组件获得焦点,我想:
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 (eg the inline name input from above). 如果我存储在巴黎节点参考currentlyFocusedNode
,就只要应用程序的任何其它部分修改节点(例如,从上面的内联名称输入)不同步。 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? 或者我根本不想“一成不变”?
Your question does not have an answer as asked. 您的问题没有得到答案。 And it seems you had a sense of that when you said 当你说时,你似乎对此有所了解
Or am I not thinking "immutable" enough at all? 或者我根本不想“一成不变”?
First you say you are using an immutable data structure. 首先,您说您正在使用不可变数据结构。 Meaning it can't be changed. 意思是它无法改变。
Then you say: 然后你说:
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 如果我在currentFocusedNode上存储了一个Paris节点引用,那么只要应用程序的任何其他部分修改节点,它就会不同步
With immutable data structures things don't get modified. 使用不可变数据结构时,事情不会被修改。 What you have is an old version of the data and a new version of the data. 您拥有的是旧版本的数据和新版本的数据。 Neither will ever change. 两者都不会改变。
So the question should really be something like: 所以问题应该是这样的:
How do I identify when 2 nodes represent the same data? 如何确定2个节点何时表示相同的数据?
Answer is use an ID. 答案是使用ID。
Another good question might be: 另一个好问题可能是:
Given a reference to an old node, tree, and newData, how can I update the tree and keep track of the node? 给定对旧节点,树和newData的引用,如何更新树并跟踪节点?
This depends largely on how the rest of the code works and what parts you have access to. 这在很大程度上取决于代码的其余部分如何工作以及您可以访问哪些部分。 Eg you could have something like this: 你可以这样:
function updateNodeInTree(nodeId, newData, inTree){
oldNode = findNode(nodeId, inTree);
newNode = merge(oldNode, newData);
newTree = merge(inTree, {path: {to: newNode}});
return [newTree, newNode];
}
But if you don't have access to where the tree is updated, you may have to settle for: 但是,如果您无法访问树的更新位置,则可能需要满足:
newTree = updateTree(oldTree, someData);
newNode = findNode(nodeId, newTree);
Give each node a unique ID. 为每个节点提供唯一的ID。 Maintain a focused_id
value. 保持focused_id
值。
Any component rendering parts of a node can check if 任何组件呈现节点的部分都可以检查是否
this.props.node.id === this.props.focused_id
and render appropriately. 并适当地渲染。
This is where Flux architecture pattern comes in. 这就是Flux架构模式的用武之地。
I would handle it like this: 我会像这样处理它:
root
and currentlyFocusedNode
in a TreeStore where currentlyFocusedNode
either saves null
or references an object in the tree
. 保存root
和currentlyFocusedNode
在TreeStore其中currentlyFocusedNode
要么节省null
或引用的object in the tree
。 eventType: 'nodeClicked'
and payload containing the object (reference) which was clicked. 单击某个节点时,将调度一个事件(使用AppDisptacher),其中包含eventType: 'nodeClicked'
和包含单击的对象(引用)的有效内容。 currentlyFocusedNode
TreeStore听AppDispatcher并进行更改currentlyFocusedNode
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.