Home > Blockchain >  Recursively structure array of objects : ReactJS
Recursively structure array of objects : ReactJS

Time:10-04

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