我有一个由任意节点组成的不可变嵌套树(mori、immutable-js 等),想想文件浏览器。树由 React 渲染。如果代表节点的组件获得焦点,我想:
- 在节点组件上显示一个输入字段以进行更改,例如节点名称。
- 显示一个包含 UI 组件的全局面板,以根据所选节点的类型编辑当前焦点节点的其他属性。
一个简单的状态对象可能看起来像这样:
{
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>
}
现在,我如何保持对当前焦点节点的有效引用?如果我在 currentlyFocusedNode
存储了一个 Paris 节点引用,一旦应用程序的任何其他部分修改该节点(例如,从上面输入的内联名称),它就会不同步。我考虑过存储焦点节点的路径,我可以用它来检索当前引用:
currentlyFocusedNode: ['root', 'children', 0, 'children', 0]
但这对我来说也很不稳定,因为即使是树上的简单节点移动操作也可能使这条路径指向错误甚至不存在的节点。
如何使用不可变数据结构处理这些事情?还是我根本没有考虑“不可变”?
最佳答案
您的问题没有所问的答案。当你说
Or am I not thinking "immutable" enough at all?
首先,您说您正在使用不可变 数据结构。表示无法更改。
然后你说:
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
使用不可变数据结构,事物不会被修改。您拥有的是旧版本的数据和新版本的数据。两者都不会改变。
所以这个问题应该是这样的:
How do I identify when 2 nodes represent the same data?
答案是使用 ID。
另一个好问题可能是:
Given a reference to an old node, tree, and newData, how can I update the tree and keep track of the node?
这在很大程度上取决于其余代码的工作方式以及您可以访问哪些部分。例如。你可以有这样的东西:
function updateNodeInTree(nodeId, newData, inTree){
oldNode = findNode(nodeId, inTree);
newNode = merge(oldNode, newData);
newTree = merge(inTree, {path: {to: newNode}});
return [newTree, newNode];
}
但是如果您无权访问树的更新位置,您可能不得不满足于:
newTree = updateTree(oldTree, someData);
newNode = findNode(nodeId, newTree);
关于javascript - 如何将 "pointers"存储到 React/Javascript 中一棵不可变树中的嵌套节点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27413049/