Удалить объект из массива, проводник?

120
23 февраля 2021, 12:10

Подскажите как можно удалить "папку" (объект) при нажатии кнопки в нашем дереве.

Наш массив с объектами (наше дерево):

export const tree = [
  {
    id: 0,
    name: "System",
    type: "folder",
    children: [
      {
        id: 0,
        name: "bin",
        type: "folder",
        children: [
          {
            id: 0,
            name: "driver",
            format: ".exe",
            type: "doc"
          },
          {
            id: 1,
            name: "readme",
            format: ".txt",
            type: "doc"
          }
        ]
      },
      {
        id: 1,
        name: "settings",
        format: ".txt",
        type: "doc"
      },
      {
        id: 2,
        name: "install",
        format: ".exe",
        type: "doc"
      }
    ]
  },
  {
    id: 1,
    name: "Games",
    type: "folder",
    children: [
      {
        id: 0,
        name: "gta",
        type: "folder",
        children: [
          {
            id: 0,
            name: "game",
            format: ".exe",
            type: "doc"
          },
          {
            id: 1,
            name: "readme",
            format: ".txt",
            type: "doc"
          }
        ]
      },
      {
        id: 1,
        name: "pubg",
        type: "folder",
        children: [
          {
            id: 0,
            name: "data",
            type: "folder",
            children: []
          },
          {
            id: 1,
            name: "launch",
            format: ".exe",
            type: "doc"
          },
          {
            id: 2,
            name: "logs",
            format: ".txt",
            type: "doc"
          }
        ]
      },
      {
        id: 2,
        name: "nfs",
        type: "folder",
        children: [
          {
            id: 0,
            name: "play",
            format: ".exe",
            type: "doc"
          },
          {
            id: 1,
            name: "speed",
            format: ".txt",
            type: "doc"
          }
        ]
      }
    ]
  },
  {
    id: 2,
    name: "Other",
    type: "folder",
    children: [
      {
        id: 0,
        name: "User",
        type: "folder",
        children: [
          {
            id: 0,
            name: "Real",
            type: "folder",
            children: [
              {
                id: 0,
                name: "Test",
                type: "folder",
                children: []
              }
            ]
          }
        ]
      }
    ]
  }
];

В рендере при рекурсии создаем <Folder> передаем в этот компонент Folder пропсы и хендлер для удаления данного объекта

renderFolder = (folder) => (
    <Folder 
      ...
      folder={folder}
      removeFolderHandler={this.removeFolderHandler}
      ...
    >
    ...
    </Folder>
}

Вот что приходит в (folder)

{id: 0, name: "System", type: "folder", children: Array(3)}
{id: 0, name: "bin", type: "folder", children: Array(2)}
{id: 1, name: "Games", type: "folder", children: Array(3)}
{id: 0, name: "gta", type: "folder", children: Array(2)}
{id: 1, name: "pubg", type: "folder", children: Array(3)}
...

В компоненте <Folder> при нажатии <button> вызываем наш removeFolderHandler с нашим объектом

<button onClick={() => this.props.removeFolderHandler(this.props.folder)} >
    Удалить
</button>

И в наш родительский компонент в метод removeFolderHandler приходит наш "объект"

 removeFolderHandler = (folder) => {
     // ???
 }

Так вот как его найти и удалить его из нашего "дерева" tree. Собственно нужен алгоритм для removeFolderHandler.

Были попытки рекурсией искать нужную нам "папку" (объект) сравнивая с текущим, но мне сказали так делать нельзя.

Надеюсь доступно объяснил чего я хочу.

Answer 1

Ответ ниже вариант с рекурсией, там бесконечная вложенность children и ка кбез рекурсии пока не понятно! Рекурсия идет не на всё дерево, перебирая его, а только на компоненты children, остальные элементы отбрасываются только фильтром (filter()).

const newTree = tree.filter(item => {
    if (item.name === folder.name) return false;
    if (item.children.length === 0) return true;
    item.children = this.getItemByName(item.children, folder.name);
    return true;
});
console.log(newTree);
...
getItemByName = (folders, name) => {
    return forlders.filter(item => {
        if (item.name === name) return false;
        if (item.children.length === 0) return true;
        item.children = this.getItemByName(item.children, name);
        return true;
    });  
}
READ ALSO
Валидация input[type=radio]

Валидация input[type=radio]

Народ, подскажите кто может знает, как в этот цикл добавить проверку на заполнение input [type="radio"]Сейчас проверяет только текстовые input

189
HTMLCollection в componentDidMount пустой

HTMLCollection в componentDidMount пустой

Необходимо поместить в React-компонент HTML полученный извне и произвести с ним ряд манипуляций (навесить обработчики на ссылки)Для этого сделан...

125
Slick Slider не переключает слайды, если их мало

Slick Slider не переключает слайды, если их мало

На сайте есть Slick Slider с функцией Slider Syncing, то есть, когда два слайдера синхронизированные и при переключении слайдов одного из них, переключаются...

91
Баг при получении координат через e.offsetX

Баг при получении координат через e.offsetX

Хочу чтобы координаты определялись относительно моего контейнера, но при подставлении в формулу eoffsetX, каждый второй тик элемент отправляется...

105