【问题标题】:JavaScript: Best way for update all tree items?JavaScript:更新所有树项的最佳方式?
【发布时间】:2022-01-25 16:26:39
【问题描述】:

我尝试在 React 中创建侧边栏组件,我有一个像下面这样的数据结构

const links = [
  {
    label: 'Item-1',
    url: '/item-1',
  },
  {
    label: 'Item-2',
    children: [
      {
        label: 'Item-2-1',
        url: '/item-2-1',
      },
      {
        label: 'Item-2-2',
        url: '/item-2-2',
      },
      {
        label: 'Item-2-3',
        url: '/item-2-3',
      },
    ],
  },
  {
    label: 'Item-3',
    children: [
      {
        label: 'Item-3-1',
        url: '/item-3-1',
      },
      {
        label: 'Item-3-2',
        url: '/item-3-2',
      },
    ],
  },
];

所以问题是假设用户更改了 URL 和类似 http://localhost:90/item-2-3 的 URL。

我需要从侧边栏激活这个侧边栏项目,它可以嵌套。因此,首先我需要停用所有其他侧边栏项目(我不希望侧边栏中有多个选定项目),然后激活选定的侧边栏项目。

因为(如果我是正确的)我需要更新所有树项假设我将 active:false 字段添加到所有 JSON,然后我需要从树中找到正确的树项(URL === item-2 -3)添加active:true并将所有父json更新为active:true(因为有看起来选择/打开)

所以我的问题是,如果我纠正了如何以最佳方式编写此代码,我是否正确? :/

实际上,我想创建一个函数,当像 selectItemFromTree(links, '/item-2-2') 那样调用这个函数时,我得到的结果如下所示。

   const links = [
  {
    label: 'Item-1',
    url: '/item-1',
    active: false
  },
  {
    label: 'Item-2',
    active: true,
    children: [
      {
        label: 'Item-2-1',
        url: '/item-2-1',
        active: false
      },
      {
        label: 'Item-2-2',
        url: '/item-2-2',
        active: true,
      },
      {
        label: 'Item-2-3',
        url: '/item-2-3',
        active: false
      },
    ],
  },
  {
    label: 'Item-3',
    active: false,
    children: [
      {
        label: 'Item-3-1',
        url: '/item-3-1',
        active: false
      },
      {
        label: 'Item-3-2',
        url: '/item-3-2',
        active: false
      },
    ],
  },
];

【问题讨论】:

  • 您正在描述几个任务。请展示您的尝试,找出问题所在,并只关注一个问题。
  • 在您开始优化之前不要担心优化。你的工作流程听起来很正确,而且做起来也不是那么难
  • @trincot 我稍微更新了我的问题并添加了我想看到的内容:)
  • @charlietfl 我添加了我想要实现的结果数据结构。
  • 好的,但这不是免费的代码编写服务或“如何”教程服务。所期望的是,当他们没有按预期工作时,您会展示您解决自己问题的尝试和其他人的帮助

标签: javascript reactjs tree


【解决方案1】:

您必须递归遍历树并更新所有活动状态。

const links=[{label:"Item-1",url:"/item-1"},{label:"Item-2",children:[{label:"Item-2-1",url:"/item-2-1"},{label:"Item-2-2",url:"/item-2-2"},{label:"Item-2-3",url:"/item-2-3"}]},{label:"Item-3",children:[{label:"Item-3-1",url:"/item-3-1"},{label:"Item-3-2",url:"/item-3-2"}]}];


const updateActiveLink = (links, url, parent = null) => {
   for (link of links) {
      link.active = false;
      if (link?.children) {
          updateActiveLink(link.children, url, link)
      }
      if (link.url === url) {
          link.active = true;
          if (!!parent) parent.active = true;
      }
   }
}

updateActiveLink(links, '/item-2-3');
          
console.log(links);
.as-console-wrapper {min-height: 100%!important; top: 0}

注意此方法会改变链接数组。

【讨论】:

  • 感谢您的回复:) 但是在您的示例中,它并不能完全满足我的需要。因此,您只需从树中更新特定项目,但我还需要将此项目的所有父项更新为活动:true。所以实际问题是这样的:)
  • 我已经更新了我的答案。您只需将父级作为函数的第三个参数传递,如果找到任何匹配项,则更新父级的活动状态。
猜你喜欢
  • 1970-01-01
  • 2010-11-22
  • 1970-01-01
  • 2013-02-23
  • 2021-03-07
  • 2018-05-14
  • 1970-01-01
  • 1970-01-01
  • 2015-11-03
相关资源
最近更新 更多