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
3
Answers
Your
data
structure is different fromtreeData
, although the children are in the same format.Instead of an object at the top-level:
you should have an array with
key
,label
andchildren
:If you really can’t edit the
data
(it’s right there …) you could map the top-level entries using the property name askey
andlabel
:Added in response to comment
If that’s your preferred input format then you could put the data conversion into your
Tree
component:In tree.js you can validate if data is not an array and transform it:
Tree.js
https://codesandbox.io/s/react-hooks-counter-demo-forked-3hxcgq
you could write the
Tree
component like this and pass down the key (category
) and the value (items
) ofObject.entries
as props toTreeNode
In the
TreeNode
you can recursively renderTreeNode
components based on if it has children or not. Here is a resource on that.Also you can add styles only to the first level.
I used a prop called
level
and defaulted it to 1, then I give styles only if the level is 1 (used inline styles for simplicity). For the next levels, I increment the level prop by 1.