Skip to content

tree的搜索、记录完整逻辑记录

1、模糊搜索过滤函数

该函数传入一个antd的tree结构的数组和搜索值,返回对应的模糊搜索keys和节点,节点仅包含自身和其所有子节点;

tsx
const filterTreeb = <T extends ITreeData>(
    data: T[],
    treeSearch: string
  ): {
    filteredKeys: React.Key[];
    filteredTree: T[];
  } => {
    const filteredKeys = new Set<React.Key>();

    const filteredTree: T[] = [];

    const searchLower = treeSearch.toLowerCase();

    const hasSameKey = (data: T[], key: string): boolean => {
      return data.some(
        (item) =>
          item.key === key ||
          (item.children && hasSameKey(item.children as T[], key))
      );
    };

    const filterNodes = (nodes: T[]) => {
      nodes.forEach((node) => {
        const isMatch = String(node.title).toLowerCase().includes(searchLower);

        if (
          isMatch &&
          !filteredKeys.has(node.key) &&
          !hasSameKey(filteredTree, node.key)
        ) {
          filteredKeys.add(node.key);

          filteredTree.push(node);
        }

        node.children && filterNodes(node.children as T[]);
      });
    };

    filterNodes(data);

    return { filteredKeys: Array.from(filteredKeys), filteredTree };
  };

2、当需要根据一些checkedKeys来做处理

使用上面过滤函数的时候,会丢失除了筛选出来节点的所有记录数据,如在未筛选前checked的节点数据,所以如有需要,可以设置一个global数据来记录(tree对应原有的keys状态需同时存在)

const [globalCheckedKeys,setGlobalCheckedKeys] = useState([])

可能需要做的事:

1、当更新的时候全局和当前一起更新,还需要考虑处理取消选中的时候,要在全局中去除

tsx
const onTreeCheck: TreeProps["onCheck"] = (checkedKeys) => {
  const newCheckedKeys = checkedKeys as React.Key[];

  const unCheckedKeys = treeStore.checkedKeys.filter(
    (key) => !newCheckedKeys.includes(key)
  );

  const newGlobalCheckedKeys = treeStore.globalCheckedKeys.filter(
    (key) => !unCheckedKeys.includes(key)
  );

  setTreeStore((prev) => ({
    ...prev,
    checkedKeys: newCheckedKeys,
    globalCheckedKeys: Array.from(
      new Set([...newGlobalCheckedKeys, ...newCheckedKeys])
    ),
  }));
};

2、进行搜索筛选后,从全局check中同样挑出对应的keys给当前check状态,以保证与tree数据保持一致

tsx
const onTreeSearch = () => {
  const result = filterTree(treeStore.treeData, treeStore.treeSearch);

  const getAllChildrenKeys = (node: DataNode): string[] => {
    let keys: string[] = [node.key as string];
    if (node.children) {
      node.children.forEach((child) => {
        keys = keys.concat(getAllChildrenKeys(child));
      });
    }
    return keys;
  };

  const allFilteredKeys = result.filteredTree.flatMap(getAllChildrenKeys);

  setTreeStore......
};

基于 MIT 许可发布