首页 > 解决方案 > 通过嵌套元素进行映射时,递归函数无法按预期工作

问题描述

我试图通过一个对象数组递归映射,这些对象可能嵌套了相同类型的对象。

IE,

type TOption = {
  id: string;
  name: string;
  options?: TOption;
}
const options = [
  { id: "1", name: "Option 1" },
  {
    id: "2",
    name: "Option 2",
    options: [
      {
        id: "3",
        name: "Option 3",
        options: [
          {
            id: "4",
            name: "Option 4"
          }
        ]
      }
    ]
  },
  { id: "5", name: "Option 5" }
] as TOption[];

有点前提,我正在尝试构建一个导航栏菜单,其中每个类型的元素TOption也可以有一个options类型字段的子菜单TOption。基于level,我将在 div 之外/屏幕外偏移该嵌套菜单。

无论如何,当我遍历数组时遇到了一些麻烦。这是我的 JS 化recurse方法(实际React.useCallback功能可以在下面的沙箱中看到),

  const recurse = React.useCallback(
    ({ options, level }) =>
      options.map(({ id, name, options: subOptions = [] }) =>
        subOptions.length ? (
          recurse({ options: subOptions, level: level + 1 })
        ) : (
          console.log(`My id is {id} and I'm at level {level}`)
        )
      ),
    []
  );

以上输出,

My id is 1 and I'm at level 1 
My id is 4 and I'm at level 3 
My id is 5 and I'm at level 1 

它显然只进入具有子菜单的元素,并且递归以没有子菜单的菜单结束。

我怎样才能改变它,使输出变成,

My id is 1 and I'm at level 1
My id is 2 and I'm at level 1
My id is 3 and I'm at level 2
My id is 4 and I'm at level 3
My id is 5 and I'm at level 1
// Where those at level 1 would be displayed in the "parent" menu,
// and those at level 2 would be a secondary submenu of that parent menu,
// and those at level 3 would a submenu of a secondary menu.

3 级菜单的示例是Settings -> Layout -> Theme,其结构是,

const options = [
  ...restOfOptions
  {
    id: "2",
    name: "Settings",         // level 1
    options: [
      {
        id: "3",
        name: "Layout",       // level 2
        options: [
          {
            id: "4",
            name: "Theme",    // level 3
          }
        ]
      }
    ]
  },
];

这里的问题是,如果存在子菜单,则该函数将返回该树中存在的最后一个子菜单。

神火6fq7q

在沙箱中,输出是,

My id is 1 and I'm at level 1
        My id is 4 and I'm at level 3
            My id is 6 and I'm at level 4
My id is 7 and I'm at level 1

但我正在寻找,

My id is 1 and I'm at level 1
My id is 2 and I'm at level 1
    My id is 3 and I'm at level 2
        My id is 4 and I'm at level 3
        My id is 5 and I'm at level 3
            My id is 6 and I'm at level 4
My id is 7 and I'm at level 7

标签: javascriptreactjs

解决方案


在“subOptions.length”控件中,如果有子选项,则不会写入当前数据,因为使用了递归。

实际上,需要先写入当前数据,如果有子选项,再调用。


推荐阅读