Почему не отрисовывается весь список компонентов через 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 шт):
Логика последнего компонента в том, что он в нужном мне виде отрисовывает один из объектов массива 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>