react + ts 的 treeSelect 组件实现(3) | 青训营笔记

115 阅读2分钟

这是我参与「第五届青训营」伴学笔记创作活动的第 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,然后遍历节点数据,将unfoldselected为true的节点的value值存入两个set中,分别为initialExpandedinitialSelected。最后将这两个set分别赋值给expandedselected

这样我们就可以实现默认展开和默认选中的功能了。

现在我们的组件还差一个很重要的功能。就是选择结果输入框的显示。我们将在下一节中实现这个功能。