两个独立Tree组件展开状态同步问题的解决方案求助
解决方案
问题根因
当前你在父组件中只维护了1份全局共享的展开状态,所有Tree组件都绑定同一个状态变量,操作任意Tree都会修改这份公共状态,自然会触发所有Tree同步更新展开/收起状态。
实现步骤
- 给每个Tree组件定义唯一的标识(比如
id属性),传入子组件 - 把父组件的展开状态从原来的单份结构,调整为以Tree id为key的映射结构,示例:
// 原单份状态写法 const [expandedKeys, setExpandedKeys] = useState([]) // 调整为按Tree id分组的状态结构 const [treeExpandedMap, setTreeExpandedMap] = useState({ // key为每个Tree的唯一id,value为对应Tree的展开keys数组 tree1: [], tree2: [] })
- 子组件Tree触发展开/收起事件时,将自身的id连同更新后的展开keys一起回传给父组件
- 父组件的状态更新逻辑仅修改对应id的Tree的展开状态:
const handleTreeExpand = (treeId, newExpandedKeys) => { setTreeExpandedMap(prev => ({ ...prev, [treeId]: newExpandedKeys })) }
- 给每个Tree传参时,读取对应id的状态值即可:
<Tree id="tree1" expandedKeys={treeExpandedMap.tree1} onExpand={(keys) => handleTreeExpand('tree1', keys)} /> <Tree id="tree2" expandedKeys={treeExpandedMap.tree2} onExpand={(keys) => handleTreeExpand('tree2', keys)} />
动态Tree适配方案
如果你的Tree是动态渲染的(比如从接口返回列表批量生成多个Tree),可以在初始化状态时自动生成映射结构:
const treeList = [/* 动态Tree列表,每个项自带唯一id */] // 初始化状态 const [treeExpandedMap, setTreeExpandedMap] = useState(() => { return treeList.reduce((acc, tree) => { acc[tree.id] = [] // 每个Tree默认展开keys为空,可自定义默认值 return acc }, {}) }) // 遍历渲染Tree {treeList.map(tree => ( <Tree key={tree.id} expandedKeys={treeExpandedMap[tree.id]} onExpand={(keys) => handleTreeExpand(tree.id, keys)} /> ))}
内容的提问来源于stack exchange,提问作者Michael Rýdl
相关产品推荐
相关产品推荐

