I am having a object that looks like the following:
export const data = {
"Category 1": [
{
key: "1",
label: "Applications",
children: [
{
key: "3",
label: "Browser",
children: [
{
key: "4",
label: "Mozilla",
children: []
},
{
key: "5",
label: "Firefox",
children: []
}
]
}
]
}
],
"Category 2": [
{
key: "2",
label: "OS",
children: [
{
key: "6",
label: "Windows",
children: []
}
]
}
]
};
This should basically draw a tree with two entries with Category 1 and Category 2 and its children should be drawn recursively.
Category 1
---- Applications
--- Browser
--- Mozilla
--- Firefox
Category 2
---- OS
--- Windows
This should be dynamically rendered. The number of first level objects will be determined using the number of keys of the object. I have tried with an array of objects and it works. But when I am having it in the above format, I am unable to render it as a tree. Help would be greatful.
Sandbox: https://codesandbox.io/s/react-hooks-counter-demo-forked-zsxsxh?file=/src/Tree.js
When I am trying it with treeData it works, but with data inside constants.js it doesnt work.
import React from "react";
import TreeNode from "./TreeNode";
const Tree = ({ data = [] }) => {
return (
<div className="d-tree">
<ul className="d-flex d-tree-container flex-column">
{data.map((tree) => (
<TreeNode node={tree} />
))}
</ul>
</div>
);
};
export default Tree;
I tried with Object.entries to render the tree, it doesnt work
>Solution :
Your data structure is different from treeData, although the children are in the same format.
Instead of an object at the top-level:
export const data = {
"Category 1": [ ... ],
"Category 2": [ ... ],
};
you should have an array with key, label and children:
export const data = [
{
key: "Category 1",
label: "Category 1",
children: [ ... ]
}, ...
];
If you really can’t edit the data (it’s right there …) you could map the top-level entries using the property name as key and label:
const dataAsArray = Object.entries(data).map(([key, value]) =>
({ key, label: key, children: value })
)
Added in response to comment
If that’s your preferred input format then you could put the data conversion into your Tree component:
const Tree = ({ data = [] }) => {
const trees = React.useMemo(() => (
data instanceof Array
? data
: Object.entries(data).map(
([key, children]) => ({ key, label: key, children })
)
), [data]);
return (
<div className="d-tree">
<ul className="d-flex d-tree-container flex-column">
{trees.map((tree) => (
<TreeNode node={tree} />
))}
</ul>
</div>
);
};