Почему не отрисовывается весь список компонентов через map()?

Мне необходимо добавить на страницу структуру файлов, как в редакторах кода, необходимо сделать древовидную структуру. Где-то есть ошибка, но я уже не в состоянии понять, в чем проблема. Есть файл mockFiles, который представляет собой несколько вложенных друг в друга папок, а также файлов.

const files = [
    {
        id: 1,
        title: "Работа",
        type: "Folder",
        opened: true,
        level: 0,
        fatherId: null,
        children: [
            {
                id: 2,
                title: "Оборудование",
                type: "Folder",
                opened: true,
                level: 1,
                fatherId: 1,
                children: [
                    {
                        id: 3,
                        title: "MA5600",
                        type: "Folder",
                        opened: true,
                        level: 2,
                        fatherId: 2,
                        children: [
                            {
                                id: 6,
                                title: "посмотреть",
                                type: "Folder",
                                opened: true,
                                level: 3,
                                fatherId: 3,
                                children: [
                                    {
                                        id: 7,
                                        title: "конфиг",
                                        type: "File",
                                        opened: true,
                                        level: 4,
                                        fatherId: 6,
                                        children: []
                                    },
                                    {
                                        id: 8,
                                        title: "mac-адреса",
                                        type: "File",
                                        opened: true,
                                        level: 4,
                                        fatherId: 6,
                                        children: []
                                    }
                                ]
                            }
                        ]
                    },
                    {
                        id: 4,
                        title: "MA5600T",
                        type: "Folder",
                        opened: true,
                        level: 2,
                        fatherId: 2,
                        children: [
                            {
                                id: 9,
                                title: "посмотреть",
                                type: "Folder",
                                opened: true,
                                level: 3,
                                fatherId: 4,
                                children: [
                                    {
                                        id: 10,
                                        title: "конфиг",
                                        type: "File",
                                        opened: true,
                                        level: 4,
                                        fatherId: 9,
                                        children: []
                                    },
                                    {
                                        id: 11,
                                        title: "mac-адреса",
                                        type: "File",
                                        opened: true,
                                        level: 4,
                                        fatherId: 9,
                                        children: []
                                    }
                                ]
                            }
                        ]
                    },
                    {
                        id: 5,
                        title: "C300/C300M",
                        type: "Folder",
                        opened: true,
                        level: 2,
                        fatherId: 2,
                        children: [
                            {
                                id: 12,
                                title: "посмотреть",
                                type: "Folder",
                                opened: true,
                                level: 3,
                                fatherId: 5,
                                children: [
                                    {
                                        id: 13,
                                        title: "конфиг",
                                        type: "File",
                                        opened: true,
                                        level: 4,
                                        fatherId: 12,
                                        children: []
                                    },
                                    {
                                        id: 14,
                                        title: "mac-адреса",
                                        type: "File",
                                        opened: true,
                                        level: 4,
                                        fatherId: 12,
                                        children: []
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        ]
    }
]

export default files;

Все это мне необходимо отрисовать на экране. Для этого у меня есть компонент FileContainer, который содержит в себе всё дерево (для того, чтобы убрать нагромождение, убрал название классов и прочую ненужную информацию):

import mockFiles from '../../../mock-objects/files'
const FileContainer = () => {
    const [files, setFiles] = useState(null);

    useEffect(()=>{
        setFiles(mockFiles)
    }, [])

    return (
        <div>
            <div>
                <div>
                    <img/>
                </div>
                <div>
               
                </div>
            </div>
            <div>
                {files?.map(file =>
                    <TreeNode key={file.id} file={file}/>
                )}
            </div>
            <div>
                <a></a>
            </div>
        </div>
    );
};

export default FileContainer;

Вот сам компонент TreeNode, который представляет собой 1 папку либо файл из дерева:

const TreeNode = ({file}) => {
    const [item, setItem] = React.useState(file);
    return (
        <div>
            <div>
                <div>
                    {item?.type === "Folder" &&
                        <div>
                            <img/>
                        </div>
                    }
                    {item?.type === "FILE"
                        &&
                        <div>
                            <img/>
                        </div>
                    }
                    <div>
                        {item?.title}
                    </div>
                </div>
                <div>
                    <div>
                        <img/>
                    </div>
                </div>
            </div>
            {item?.children &&
                <div>
                    {item?.children.map((child) =>
                        <TreeNode key={child.id} item={child}/>
                    )}
                </div>
            }
        </div>
    );
};

export default TreeNode;

Логика последнего компонента в том, что он в нужном мне виде отрисовывает один из объектов массива mockFiles, но почему-то он работает как-то странно, и отрисовывает в результате только первую родительскую папку, а также 1 svg без текста и стрелки в качестве children. введите сюда описание изображения Почему не отрисовываются все остальные вложенные папки из объекта mockFiles?


Ответы (1 шт):

Автор решения: ksa

Логика последнего компонента в том, что он в нужном мне виде отрисовывает один из объектов массива mockFiles, но почему-то он работает как-то странно, и отрисовывает в результате только первую родительскую папку

Это не логика твоего компонента... Это ты так себе ее представляешь. А компонент работает как ты его написал. Не больше и не меньше. Может он у тебя вообще в ошибку вылетает.

Вот смотри на мой вариант - он нормально работает. Можешь взять его за основу и далее доработать под свои нужды.

//
function Itm(props) {
  const [obj, setObj] = React.useState(props.obj)
  return <li>
    <p>{obj.type} {obj.title}</p>
    <List arr={obj.children} />
  </li>
}

//
function List(props) {
  return <ul>
    {props.arr.map(o => <Itm key={o.id} obj={o} />)}
  </ul>
}

//
function App() {
  const [arr, setArr] = React.useState([])
  React.useEffect(_ => setArr(data()), [])
  return <List arr={arr} />
}

const domContainer = document.querySelector('#like_button_container');
const root = ReactDOM.createRoot(domContainer);
root.render(<App />);

//
function data() {
  return [
    {
        id: 1,
        title: "Работа",
        type: "Folder",
        opened: true,
        level: 0,
        fatherId: null,
        children: [
            {
                id: 2,
                title: "Оборудование",
                type: "Folder",
                opened: true,
                level: 1,
                fatherId: 1,
                children: [
                    {
                        id: 3,
                        title: "MA5600",
                        type: "Folder",
                        opened: true,
                        level: 2,
                        fatherId: 2,
                        children: [
                            {
                                id: 6,
                                title: "посмотреть",
                                type: "Folder",
                                opened: true,
                                level: 3,
                                fatherId: 3,
                                children: [
                                    {
                                        id: 7,
                                        title: "конфиг",
                                        type: "File",
                                        opened: true,
                                        level: 4,
                                        fatherId: 6,
                                        children: []
                                    },
                                    {
                                        id: 8,
                                        title: "mac-адреса",
                                        type: "File",
                                        opened: true,
                                        level: 4,
                                        fatherId: 6,
                                        children: []
                                    }
                                ]
                            }
                        ]
                    },
                    {
                        id: 4,
                        title: "MA5600T",
                        type: "Folder",
                        opened: true,
                        level: 2,
                        fatherId: 2,
                        children: [
                            {
                                id: 9,
                                title: "посмотреть",
                                type: "Folder",
                                opened: true,
                                level: 3,
                                fatherId: 4,
                                children: [
                                    {
                                        id: 10,
                                        title: "конфиг",
                                        type: "File",
                                        opened: true,
                                        level: 4,
                                        fatherId: 9,
                                        children: []
                                    },
                                    {
                                        id: 11,
                                        title: "mac-адреса",
                                        type: "File",
                                        opened: true,
                                        level: 4,
                                        fatherId: 9,
                                        children: []
                                    }
                                ]
                            }
                        ]
                    },
                    {
                        id: 5,
                        title: "C300/C300M",
                        type: "Folder",
                        opened: true,
                        level: 2,
                        fatherId: 2,
                        children: [
                            {
                                id: 12,
                                title: "посмотреть",
                                type: "Folder",
                                opened: true,
                                level: 3,
                                fatherId: 5,
                                children: [
                                    {
                                        id: 13,
                                        title: "конфиг",
                                        type: "File",
                                        opened: true,
                                        level: 4,
                                        fatherId: 12,
                                        children: []
                                    },
                                    {
                                        id: 14,
                                        title: "mac-адреса",
                                        type: "File",
                                        opened: true,
                                        level: 4,
                                        fatherId: 12,
                                        children: []
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        ]
    }
  ]
}
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<div id="like_button_container"></div>

→ Ссылка