ReactJS and Material UI TreeView: can I use a JSON/array of object to populate the TreeView?

11,019

The TreeView component doesn't have anything built-in for this, but it is fairly straightforward to create re-usable code to provide this functionality for a given data structure.

Here is one way to do it:

import React from "react";
import ReactDOM from "react-dom";

import TreeView from "@material-ui/lab/TreeView";
import TreeItem from "@material-ui/lab/TreeItem";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import ChevronRightIcon from "@material-ui/icons/ChevronRight";
import { sampleFromStackOverflowQuestion, seasons } from "./sampleData";

const getTreeItemsFromData = treeItems => {
  return treeItems.map(treeItemData => {
    let children = undefined;
    if (treeItemData.children && treeItemData.children.length > 0) {
      children = getTreeItemsFromData(treeItemData.children);
    }
    return (
      <TreeItem
        key={treeItemData.id}
        nodeId={treeItemData.id}
        label={treeItemData.name}
        children={children}
      />
    );
  });
};
const DataTreeView = ({ treeItems }) => {
  return (
    <TreeView
      defaultCollapseIcon={<ExpandMoreIcon />}
      defaultExpandIcon={<ChevronRightIcon />}
    >
      {getTreeItemsFromData(treeItems)}
    </TreeView>
  );
};

function App() {
  return (
    <div className="App">
      <DataTreeView treeItems={sampleFromStackOverflowQuestion} />
      <br />
      <DataTreeView treeItems={seasons} />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Edit Data-driven TreeView

DataTreeView and getTreeItemsFromData could be moved into a separate file and then imported in order to reuse them in multiple components.

Here is a Typescript version:

import * as React from "react";

import TreeView from "@material-ui/lab/TreeView";
import TreeItem from "@material-ui/lab/TreeItem";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import ChevronRightIcon from "@material-ui/icons/ChevronRight";
import {
  sampleFromStackOverflowQuestion,
  seasons,
  TreeItemData
} from "./sampleData";

const getTreeItemsFromData = (treeItems: TreeItemData[]) => {
  return treeItems.map(treeItemData => {
    let children = undefined;
    if (treeItemData.children && treeItemData.children.length > 0) {
      children = getTreeItemsFromData(treeItemData.children);
    }
    return (
      <TreeItem
        key={treeItemData.id}
        nodeId={treeItemData.id}
        label={treeItemData.name}
        children={children}
      />
    );
  });
};
interface DataTreeViewProps {
  treeItems: TreeItemData[];
}
function DataTreeView({ treeItems }: DataTreeViewProps) {
  return (
    <TreeView
      defaultCollapseIcon={<ExpandMoreIcon />}
      defaultExpandIcon={<ChevronRightIcon />}
    >
      {getTreeItemsFromData(treeItems)}
    </TreeView>
  );
}

export default function App() {
  return (
    <div className="App">
      <DataTreeView treeItems={sampleFromStackOverflowQuestion} />
      <br />
      <DataTreeView treeItems={seasons} />
    </div>
  );
}

Edit Typescript data-driven TreeView

Share:
11,019
devamat
Author by

devamat

Updated on June 28, 2022

Comments

  • devamat
    devamat almost 2 years

    I have an array of object containing the values that need to populate the <TreeView> component:

    const treeItems = [
        {
            id: uuidv4(),
            name: 'English',
            children: [
                {
                    id: uuidv4(),
                    name: 'Spring',
                    children: []
                }
            ]
        },
        {
            id: uuidv4(),
            name: 'Italian',
            children: [
                {
                    id: uuidv4(),
                    name: 'Level A',
                    children: []
                }
            ]
        }
    ]
    

    I would like to use it as a prop to automatically populate the TreeView with TreeItems.

    Currently I have a function that renders the children when you pass the array, but checking the documentation (https://material-ui.com/api/tree-view/) I noticed that there is a prop for children.

    children node The content of the component.

    Is it possible to use JSON/array of object to populate the TreeView?