我用react / redux建立一个树视图。折叠/展开节点时,会调度一个操作,以便切换"切换" field设置为true / false。 下面的数组是我的redux状态的一部分。
Tree:{
"id" : 1,
"name": "Demo",
"toggled": true,
"active": false,
"children": [
{
"id" : 21,
"name": "example",
"active": false,
"toggled": false,
children:[...]
}
}
以下功能不好,只返回第一级节点更新的树,而不是嵌套的
function createNodes(children,corporation,type){
if (!Array.isArray(children))
{
children = children ? [children] : [];
}
return children.map(node => {
createNodes(node.children,corporation,type);
if(node.id!==corporation.id){
return ({...node,active:false}: node);
}
return ({...node,toggled:corporation.toggled});
}
知道如何才能有效地做到这一点吗?
欢呼声
答案 0 :(得分:4)
通常建议您尽可能保持您的州一样平坦。我会尝试将您的状态更改为平面数组,然后更新children
属性以包含ID列表而不是子项本身。像这样:
<强>国家强>
[
{
"id" : 1,
"name": "Demo",
"toggled": true,
"active": false,
"children": [ "21" ]
},
{
"id" : 21,
"name": "example",
"active": false,
"toggled": false,
children:[...]
}
]
您的reducer将成为一个简单的列表更新:
<强>减速强>
function updateCorporation(state, newCorp) {
return state.map(function(corp) {
return corp.id === newCorp.id ? newCorp : corp
})
}
深度更新
但是,如果您无法使用平面状态并需要在深树上进行更新,则尝试修复原始createNodes
功能。我认为主要问题是你没有使用递归来生成返回值,你只是在其自身内部调用函数。尝试这样的事情(我已经放弃了type
,因为你没有使用它):
function createNodes(state, corporation) {
if (state.id === corporation.id) {
return { ...state, toggled: corporation.toggled }
} else if (Array.isArray(state.children)) {
const children = state.children.map(function(child){
return createNodes(child, corporation)
})
return { ...state, children }
} else {
return state
}
}