Implementing a Treeview component using React Today after watching a getting started course about React, I tried to code my very first React component, a "treeview" as the title says. It does work, but as a newbie I know there are many improvement that can be done. 

It receives a data array like the one below:

[{
    descp: 'UNE',
    url: '/tree/une',
    icon: 'icon-list',
    children: [
        {
            descp: 'ATI',
            url: '/tree/une/ati',
            icon: 'icon-layers',
            children: [{
                    descp: 'ATI-VC',
                    url: '/tree/une/ati/ativc',
                    icon: 'icon-pin',
                    children: []
                },
                {
                    descp: 'ATI-CMG',
                    url: '/tree/une/ati/aticmg',
                    icon: 'icon-pin',
                    children: []
                }
            ]
        },
        {
            descp: 'EMGEF',
            url: '/tree/une/emgef',
            icon: 'icon-layers',
            children: []
        },
        {
            descp: 'ECIE',
            url: '/tree/une/ecie',
            icon: 'icon-layers',
            children: []
        },
        {
            descp: 'GEYSEL',
            url: '/tree/une/geysel',
            icon: 'icon-layers',
            children: []
        }
    ]
}]


Maybe the data format can be improve as well but the real deal is the component:

const MyTree = (props) =&gt; {
    const { list } = props;
    return (
        list.map((child,i)=&gt;
            &lt;MyTreeNestedItems key={i} data={child} /&gt;
        )
    );
};


const MyTreeNestedItems = (props) =&gt; {
    const { data } = props;

    const createChildren = (list) =&gt; {
        return (
            list.map((child,i)=&gt;
                &lt;MyTreeNestedItems key={i} data={child} /&gt;
            )
        )
    }

    let children = null;
    if (data.children.length) {
        children = createChildren(data.children);
    }

    return (
        &lt;li className="nav-item"&gt;
            &lt;a className="nav-link" href="#"&gt;
                &lt;span className={data.icon}&gt;&lt;/span&gt; {" "}
                { data.descp }
            &lt;/a&gt;
            &lt;ul style={{listStyleType:"none"}}&gt;{children}&lt;/ul&gt;
        &lt;/li&gt;
    );
};

render(&lt;MyTree list={tree} /&gt;,document.querySelector('.js-mytree'));


Any tips would be gratefully appreciated.
You might notice that createChildren is almost the same as MyTree -- the only difference is that createChildren takes its argument directly instead of as a props object. So with a small change we can remove createChildren entirely:

const MyTreeNestedItems = (props) =&gt; {
    const { data } = props;

    let children = null;
    if (data.children.length) {
      children = &lt;MyTree list={data.children} /&gt;;
    }

    return (
        &lt;li className="nav-item"&gt;
            &lt;a className="nav-link" href="#"&gt;
                &lt;span className={data.icon}&gt;&lt;/span&gt; {" "}
                { data.descp }
            &lt;/a&gt;
            &lt;ul style={{listStyleType:"none"}}&gt;{children}&lt;/ul&gt;
        &lt;/li&gt;
    );
}


This can be a bit more compact as so:

const MyTreeNestedItems = ({ data }) =&gt; {
    return (
        &lt;li className="nav-item"&gt;
            &lt;a className="nav-link" href="#"&gt;
                &lt;span className={data.icon}&gt;&lt;/span&gt; {" "}
                { data.descp }
            &lt;/a&gt;
            &lt;ul style={{listStyleType:"none"}}&gt;
                {data.children.length ? &lt;MyTree list={data.children} /&gt; : null}
            &lt;/ul&gt;
        &lt;/li&gt;
    );
};




Currently this code renders invalid HTML -- it renders with a &lt;li&gt; as the top level element but &lt;li&gt; should only be contained in a &lt;ul&gt;, &lt;ol&gt;, or &lt;menu&gt;.

Looking at the code so far, &lt;MyTree&gt; is rendered in two places -- it may be tempting to just add another &lt;ul&gt; around &lt;MyTree list={tree} /&gt; in the render() call. But then we would have two occurrences of a structure like this: &lt;ul&gt;&lt;MyTree/&gt;&lt;/ul&gt;. It'd be easier to just move the &lt;ul&gt; into the &lt;MyTree/&gt;.

With that, the code now looks like this:

const MyTree = ({ list }) =&gt; {
    return (
        &lt;ul style={{listStyleType:"none"}}&gt;
            {list.map((child,i)=&gt; &lt;MyTreeNestedItems key={i} data={child} /&gt;)}
        &lt;/ul&gt;
    );
};

const MyTreeNestedItems = ({ data }) =&gt; {
    return (
        &lt;li className="nav-item"&gt;
            &lt;a className="nav-link" href="#"&gt;
                &lt;span className={data.icon}&gt;&lt;/span&gt; {" "}
                { data.descp }
            &lt;/a&gt;
            {data.children.length ? &lt;MyTree list={data.children} /&gt; : null}
        &lt;/li&gt;
    );
};

render(&lt;MyTree list={tree} /&gt;, document.querySelector('.js-mytree'));




From here it's a matter of taste. Both of the components are just directly returning a value, so we can use short arrow function syntax now: (...) =&gt; (value) instead of (...) =&gt; { return (value); }

Also, the components are now simple enough that I would just combine the two.

All in, that leaves us with this final version of the code:

const MyTree = ({ list }) =&gt; (
    &lt;ul style={{listStyleType:"none"}}&gt;
        {list.map(({icon, descp, children}, i) =&gt; (
            &lt;li className="nav-item" key={i}&gt;
                &lt;a className="nav-link" href="#"&gt;
                    &lt;span className={icon} /&gt; {descp}
                &lt;/a&gt;
                {children.length ? &lt;MyTree list={children} /&gt; : null}
            &lt;/li&gt;
        ))}
    &lt;/ul&gt;
);

render(&lt;MyTree list={tree} /&gt;, document.querySelector('.js-mytree'));