假设我们有mytree -
const mytree =
{ id: 1, active: false, children: [
{ id: 11, active: true, children: [
{ id: 111, active: false },
{ id: 112, active: true }
]
},
{ id: 12, active: false },
{ id: 13, active: true, children: [
{ id: 131, active: false }
]
}
]
}
您可以不可变地更新使用递归函数recUpdate -
const recUpdate = (t, f) =>
({ ...t, children: t?.children?.map(c => recUpdate(c, f)), ...f(t) })
我们的高阶函数可以专门写成activate和deactivate——
const activate = t =>
recUpdate(t, _ => ({ active: true }))
const deactivate = t =>
recUpdate(t, _ => ({ active: false }))
调用activate 将生成一棵新树,其中所有active = true -
console.log(activate(mytree))
{ id: 1, active: true, children: [
{ id: 11, active: true, children: [
{ id: 111, active: true },
{ id: 112, active: true }
]
},
{ id: 12, active: true },
{ id: 13, active: true, children: [
{ id: 131, active: true }
]
}
]
}
调用deactivate 将生成一棵新树,其中所有active = false -
console.log(deactivate(mytree))
{ id: 1, active: false, children: [
{ id: 11, active: false, children: [
{ id: 111, active: false },
{ id: 112, active: false }
]
},
{ id: 12, active: false },
{ id: 13, active: false, children: [
{ id: 131, active: false }
]
}
]
}
mytree 没有变异 -
console.log(mytree)
{ id: 1, active: false, children: [
{ id: 11, active: true, children: [
{ id: 111, active: false },
{ id: 112, active: true }
]
},
{ id: 12, active: false },
{ id: 13, active: true, children: [
{ id: 131, active: false }
]
}
]
}
展开下面的sn-p,在浏览器中验证结果-
const recUpdate = (t, f) =>
({ ...t, children: t?.children?.map(c => recUpdate(c, f)), ...f(t) })
const activate = t =>
recUpdate(t, _ => ({ active: true }))
const deactivate = t =>
recUpdate(t, _ => ({ active: false }))
const mytree =
{ id: 1, active: false, children: [
{ id: 11, active: true, children: [
{ id: 111, active: false },
{ id: 112, active: true }
]
},
{ id: 12, active: false },
{ id: 13, active: true, children: [
{ id: 131, active: false }
]
}
]
}
console.log(JSON.stringify(activate(mytree)))
console.log(JSON.stringify(deactivate(mytree)))
console.log(JSON.stringify(mytree))