这是我参与「第五届青训营」伴学笔记创作活动的第 15 天,昨天我们实现了一个树状数据的展开收起以及选择的基本逻辑,为了让这些基础功能能够拥有适用于更多的使用场景,我们还需要进行一些优化。
显示树形结构
我们将使用一个变量来控制是否显示树形结构,当点击输入框时,我们将变量设置为true,当点击树形结构时,我们将变量设置为false。同样是使用useState来实现。
const [displayTree, setDisplayTree] = useState(false);
当这个参数被设置为true时,我们改变树选择菜单的样式,这里使用classnames库来实现多个样式的组合。关于这个库的相关信息可以参考classnames。
默认展开或选中
对于节点数据,我们加入两个参数,一个是unfold,一个是selected。当unfold为true时,该节点会默认展开,当selected为true时,该节点会默认选中。
export interface TreeNode<T> {
value: T;
label: string;
children?: TreeNode<T>[];
unfold?: boolean;
selected?: boolean;
}
为了能够实现这个功能,我们需要在初始化的时候,遍历节点数据,将unfold和selected为true的节点的value值存入两个set中,分别为initialExpanded和initialSelected。
useEffect(() => {
const initialSelected: Array<TreeNode<T>> = [];
const initialExpanded: Set<T> = new Set();
if (displaySelect !== undefined) {
setDisplayTree(displaySelect);
}
const traverse = (node: TreeNode<T>) => {
if (node.defaultSelected) {
initialSelected.push(node);
}
if (node.unfold && node.children) {
initialExpanded.add(node.value);
}
if (node.children) {
node.children.forEach((child: TreeNode<T>) => {
traverse(child);
});
}
};
data.forEach((node: TreeNode<T>) => {
traverse(node);
});
setSelected(initialSelected);
setExpanded(initialExpanded);
}, []);
在上述代码中,我们使用了useEffect来实现初始化的功能,这个函数会在组件挂载时执行,当依赖项发生变化时,也会执行。这里我们将依赖项设置为空数组,这样就只会在组件挂载时执行一次。
在这个函数中初始化了两个set,然后遍历节点数据,将unfold和selected为true的节点的value值存入两个set中,分别为initialExpanded和initialSelected。最后将这两个set分别赋值给expanded和selected。
这样我们就可以实现默认展开和默认选中的功能了。
现在我们的组件还差一个很重要的功能。就是选择结果输入框的显示。我们将在下一节中实现这个功能。