1

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.

2 Answers 2

1

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>
  );
}
Sign up to request clarification or add additional context in comments.

Comments

1

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} />

4 Comments

< span className = "line" /> shoul be present only for children
@li87 Corrected the code by negation.
Thanks much for the answer
@li97 So mark it as an answer or vote it up. These things matter.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.