Remove/Add 单击父节点时,数组中树的所有子节点

Remove/Add all childrenNode of a tree from an array when clicking on a parentNode

我有这个嵌套对象:

export interface RenderTree {
    id: string;
    name: string;
    children?: readonly RenderTree[];
}

export const UserLoginRoleV2Tree: RenderTree = {
    id: "root",
    name: "APP",
    children: [
        {
            id: "1",
            name: UserLoginRoleV2.DASHBOARD
        },
        {
            id: "2",
            name: UserLoginRoleV2.REPORTING,
            children: [
                {
                    id: "2.1",
                    name: UserLoginRoleV2.REPORTS
                },
                {
                    id: "2.2",
                    name: UserLoginRoleV2.SALES_DETAILS
                },
                {
                    id: "2.3",
                    name: UserLoginRoleV2.LEADS_DETAILS
                }
            ]
        },
        {
            id: "3",
            name: UserLoginRoleV2.SALES_DATA,
            children: [
                {
                    id: "3.1",
                    name: UserLoginRoleV2.SALES
                },
                {
                    id: "3.2",
                    name: UserLoginRoleV2.LEADS
                },
                {
                    id: "3.3",
                    name: UserLoginRoleV2.CALLS
                },
                {
                    id: "3.4",
                    name: UserLoginRoleV2.PHONE_CLOSING
                }
            ]
        },
        {
            id: "4",
            name: UserLoginRoleV2.TRACKING,
            children: [
                {
                    id: "4.1",
                    name: UserLoginRoleV2.UNIVERSAL_SCRIPT
                },
                {
                    id: "4.2",
                    name: UserLoginRoleV2.SOURCE_LINKS
                },
                {
                    id: "4.3",
                    name: UserLoginRoleV2.URL_RULES
                },
                {
                    id: "4.4",
                    name: UserLoginRoleV2.PRODUCTS
                },
                {
                    id: "4.4",
                    name: UserLoginRoleV2.TAGS
                }
            ]
        },
        {
            id: "5",
            name: UserLoginRoleV2.SETTINGS,
            children: [
                {
                    id: "5.1",
                    name: UserLoginRoleV2.PROFILE
                },
                {
                    id: "5.2",
                    name: UserLoginRoleV2.BILLING
                },
                {
                    id: "5.3",
                    name: UserLoginRoleV2.SUB_USERS
                },
                {
                    id: "5.4",
                    name: UserLoginRoleV2.CONNECTED_ACCOUNTS
                },
                {
                    id: "5.5",
                    name: UserLoginRoleV2.INTEGRATIONS
                },
                {
                    id: "5.6",
                    name: UserLoginRoleV2.TRACKING_SETTINGS
                },
                {
                    id: "5.7",
                    name: UserLoginRoleV2.TRACKING_DOMAINS
                }
            ]
        }
    ]
}

从这个对象,我可以构建一个 Tree。树的每个节点都有一个复选框。要知道复选框是否被选中,当我保留所有被选中的节点时,我有一个状态数组:

interface State {
    roles: Array<string>;
}
        <TreeItem key={nodes.id} nodeId={nodes.id} label={<Checkbox checked={this.state.roles.includes(nodes.name)} onClick={...}>
          {Array.isArray(nodes.children)
            ? nodes.children.map((node) => this.renderTree(node))
            : null}
        </TreeItem>

我正在寻找一种方法,在单击某个节点时从数组中删除该节点的所有子节点,因为我知道一个子节点也可以有子节点。

我觉得我们可以用递归函数来实现它,但我现在还没有成功。你能帮帮我吗?

好的,我用 Depth-first search

解决了它
/**
 * Get all children of a node.
 * @param branch The node whose children you want to know
 * @param callback Function to apply on each node.
 */
const breadthFirstSearch = (branch: TreeBranch): TreeBranch[] => {
    let queue = new Array(branch);
    let explored = new Array(branch);
    let res = new Array();
    let b: TreeBranch;
    while (queue.length !== 0) {
        b = queue.shift();
        res.push(b);
        b.children?.forEach(child => {
            if (!explored.includes(child)) {
                queue.push(child);
                explored.push(child);
            }
        })
    }
    return res;
}