I am trying to render an array as a nested tree which can go up-to n levels. Basically I have an JSX that depicts parent and children. Based on if the node is parent or child , I need to render the tree by attaching classname.
JSX of the parent looks like:
<div className="level-0 group">
<div className="details-holder">
<span className="item-text">{name}</span>
</div>
</div>
JSX of the children look like:
<div className="level-1 leaf">
<span className="line" />
<div className="details-holder">
<span className="item-text">{name}</span>
</div>
</div>
<div className="level-2 leaf">
<span className="line" />
<div className="details-holder">
<span className="item-text">{name}</span>
</div>
</div>
These JSX needs to rendered dynamically based on the array of the objects with the follolwing structure
[{
"name": "abc",
"className": "level-0 group",
"children": [{
"name": "abc.xyz",
"className": "level-1 leaf",
"children": [{
"className": "level-2 leaf",
"name": "abc.xyz.pqr",
"children": []
}]
}]
}]
So ideally the parent should have level-0 group
class, children level-1 leaf
, grandchildren level-2 leaf
and so on.
Code that I tried is below, but how would I do it dynamically
return(
{ data.map(item => {
<>
<div className=`${item.className}`>
<div className="details-holder">
<span className="item-text">{item.name}</span>
</div>
</div>
<div className={`${item[0].children[0].className`}>
<span className="line" />
<div className="details-holder">
<span className="item-text">{item[0].children[0].name}</span>
</div>
</div>
<div className={`${item[0].children[1].className`}>
<span className="line" />
<div className="details-holder">
<span className="item-text">{item[0].children[1].name}</span>
</div>
</div>
</>
}
}
)
Thanks for the help.
CodePudding user response:
Please check this if it's work for you. It more in modular form which help you to update the parent and child HTML fragment separately.
const Parent = (item) => (
<div className={`${item.className}`}>
<div className="details-holder">
<span className="item-text">{item.name}</span>
</div>
</div>
);
const Child = (item) => (
<div className={`${item.className}`}>
<span className="line" />
<div className="details-holder">
<span className="item-text">{item.name}</span>
</div>
{item.children.map((ch) => (
<Child {...ch} />
))}
</div>
);
export default function App() {
return (
<div className="App">
{data.map((item) => (
<>
<Parent {...item} />
{item.children.map((ch) => (
<Child {...ch} />
))}
</>
))}
</div>
);
}
CodePudding user response:
This is actually very simple if you implement the recursion inside the component. Just pass children as data into the same component calling itself.
const Tree = (props) => {
return <>
{
props.data.map((item) => {
return <div className = {item.className} > {
(props.level !== 0) && < span className = "line" />
} <div className = "details-holder" >
<span className = "item-text" > {name} </span> </div> {
props.data.children.map(() => <Tree data={item.children} level={props.level 1} > )
} </div>
})
}
</>
}
<Tree data={data} level={0} />