Skip to content

Modus-Logo-Long-BlackCreated with Sketch.

  • Services
  • Work
  • Blog
  • Resources

    OUR RESOURCES

    Innovation Podcast

    Explore transformative innovation with industry leaders.

    Guides & Playbooks

    Implement leading digital innovation with our strategic guides.

    Practical guide to building an effective AI strategy
  • Who we are

    Our story

    Learn about our values, vision, and commitment to client success.

    Open Source

    Discover how we contribute to and benefit from the global open source ecosystem.

    Careers

    Join our dynamic team and shape the future of digital transformation.

    How we built our unique culture
  • Let's talk
  • EN
  • FR

Ext JS to React: Tree

Published on February 22, 2018
Last Updated on April 8, 2021
Application Development

This is part of the Ext JS to React blog series. You can review the code from this article on the Ext JS to React Git repo.

Not all data can be presented in a simple grid since not all data is flat. Take, for example, the file system on your computer. Folders can hold files as well as other nested folders, allowing your data to be organized in a hierarchical (or tree) shape. In Ext JS, a tree panel is effectively a grid with a column that displays the names of the files and folders along with an icon used to toggle the collapse state of each parent node. With ag-Grid, the same is true. We’ve been using ag-Grid as a pre-built solution to display grids and we’ll continue to use it to display a tree.

Note: While many features from ag-Grid are free, displaying data in a tree with ag-Grid is part of their enterprise pricing model. For this demonstration, you can sign up for a trial enterprise license.

Note: While not a requirement for React, this article’s code examples assume you’re starting with a starter app generated by create-react-app.

ag-Grid setup

First, install ag-Grid including the files we’ll use to theme the grid:

npm install --save ag-grid
npm install --save ag-grid-react
npm install --save ag-grid-enterprise

If you’re using React 16+ you may also need to install react-dom-factories:

npm install --save react-dom-factories

Sample Tree Data

Below is the data we’ll use for our two tree examples:

const data = [
  {
    orgHierarchy: ['Erica Rogers'],
    jobTitle: 'CEO',
    employmentType: 'Permanent',
    email: 'erica.rogers@acme.com'
  },
  {
    orgHierarchy: ['Erica Rogers', 'Malcolm Barrett'],
    jobTitle: 'Exec. Vice President',
    employmentType: 'Permanent',
    email: 'malcolm.barrett@acme.com'
  },
  {
    orgHierarchy: ['Erica Rogers', 'Malcolm Barrett', 'Esther Baker'],
    jobTitle: 'Director of Operations',
    employmentType: 'Permanent',
    email: 'esther.baker@acme.com'
  },
  {
    orgHierarchy: ['Erica Rogers', 'Malcolm Barrett', 'Esther Baker', 'Brittany Hanson'],
    jobTitle: 'Fleet Coordinator',
    employmentType: 'Permanent',
    email: 'brittany.hanson@acme.com'
  },
  {
    orgHierarchy: ['Erica Rogers', 'Malcolm Barrett', 'Esther Baker', 'Brittany Hanson', 'Leah Flowers'],
    jobTitle: 'Parts Technician',
    employmentType: 'Contract',
    email: 'leah.flowers@acme.com'
  },
  {
    orgHierarchy: ['Erica Rogers', 'Malcolm Barrett', 'Esther Baker', 'Brittany Hanson', 'Tammy Sutton'],
    jobTitle: 'Service Technician',
    employmentType: 'Contract',
    email: 'tammy.sutton@acme.com'
  },
  {
    orgHierarchy: ['Erica Rogers', 'Malcolm Barrett', 'Esther Baker', 'Derek Paul'],
    jobTitle: 'Inventory Control',
    employmentType: 'Permanent',
    email: 'derek.paul@acme.com'
  },
  {
    orgHierarchy: ['Erica Rogers', 'Malcolm Barrett', 'Francis Strickland'],
    jobTitle: 'VP Sales',
    employmentType: 'Permanent',
    email: 'francis.strickland@acme.com'
  },
  {
    orgHierarchy: ['Erica Rogers', 'Malcolm Barrett', 'Francis Strickland', 'Morris Hanson'],
    jobTitle: 'Sales Manager',
    employmentType: 'Permanent',
    email: 'morris.hanson@acme.com'
  },
  {
    orgHierarchy: ['Erica Rogers', 'Malcolm Barrett', 'Francis Strickland', 'Todd Tyler'],
    jobTitle: 'Sales Executive',
    employmentType: 'Contract',
    email: 'todd.tyler@acme.com'
  },
  {
    orgHierarchy: ['Erica Rogers', 'Malcolm Barrett', 'Francis Strickland', 'Bennie Wise'],
    jobTitle: 'Sales Executive',
    employmentType: 'Contract',
    email: 'bennie.wise@acme.com'
  },
  {
    orgHierarchy: ['Erica Rogers', 'Malcolm Barrett', 'Francis Strickland', 'Joel Cooper'],
    jobTitle: 'Sales Executive',
    employmentType: 'Permanent',
    email: 'joel.cooper@acme.com'
  }
];

The data structure is flat. The orgHierarchy array is what is used to build the parent child relationship. Effectively, that array is the hierarchy. ag-Grid loops through the array, finds the matching node as a parent and adds data to that parent. The other fields in the data are for the last entry in the orgHierarchy array.

ag-Grid Tree Configuration

With Ext JS, the TreeStore does most of the data handling. It creates all the records and nests them in childNodes array. This is almost exactly how JavaScript manages the DOM. Child nodes are in an element’s childNodes property. With ag-Grid, the data is flat, but is given an array to build the hierarchy for you automatically. Below is an example of the Tree component:

import React, { Component } from 'react';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid/dist/styles/ag-grid.css';
import 'ag-grid/dist/styles/ag-theme-material.css';
import 'ag-grid-enterprise';

import {LicenseManager} from "ag-grid-enterprise/main";
// The tree view from ag-Grid requires an enterprise license and a product key
// Pricing: https://www.ag-grid.com/license-pricing.php
// Trial: https://www.ag-grid.com/start-trial.php
LicenseManager.setLicenseKey("your license key");

class App extends Component {
  columns = [
    {
      field: 'jobTitle'
    },
    {
      field: 'employmentType'
    }
  ]

  getDataPath = (data) => {
    return data.orgHierarchy;
  }

  autoGroupColumnDef = {
    headerName: 'Organization Hierarchy',
    width: 300,
    cellRendererParams: {
      suppressCount: true
    }
  }

  render () {
    return (
      <div className="ag-theme-material">
        <AgGridReact
          containerStyle={{height: '400px'}}
          columnDefs={this.columns}
          rowData={data}
          treeData={true}
          getDataPath={this.getDataPath}
          autoGroupColumnDef={this.autoGroupColumnDef}
        />
      </div>
    );
  }
}

export default App;

This looks very similar to the grids we’ve configured before, but there are three key configs:

  • treeData: This is pretty self documenting, but it tells the grid that it will be working with data to display a tree
  • getDataPath: A function that will return the array that will be used to build the hierarchical data
  • autoGroupColumnDef: A column definition (like what we have in the columns array) that will be added to display the tree UI bits like the expand / collapse icon. This column can be thought of as the “tree column”.
Ext JS to React: Tree, Simple

You can review the sample code on the Git repo.

ag-Grid Tree Features

As we’ve seen in the Features and Plugins article, ag-Grid’s grid component offers advanced features above and beyond the basic implementation. Since the ag-Grid tree is just a grid, the same features we’ve seen used with the grid can be used by the tree:

import React, { Component } from 'react';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid/dist/styles/ag-grid.css';
import 'ag-grid/dist/styles/ag-theme-material.css';
import 'ag-grid-enterprise';

import {LicenseManager} from "ag-grid-enterprise/main";
// The tree view from ag-Grid requires an enterprise license and a product key
// Pricing: https://www.ag-grid.com/license-pricing.php
// Trial: https://www.ag-grid.com/start-trial.php
LicenseManager.setLicenseKey("your license key");

class App extends Component {
  columns = [
    {
      field: 'jobTitle',
      editable: true
    },
    {
      field: 'employmentType'
    },
    {
      field: 'email',
      cellRenderer: params => {
        return `<a href="mailto:${params.value}">${params.value}</a>`;
      }
    }
  ]

  getDataPath = (data) => {
    return data.orgHierarchy;
  }
  autoGroupColumnDef = {
    headerName: 'Organisation Hierarchy',
    width: 300,
    pinned: 'left',
    editable: true,
    cellRendererParams: {
      suppressCount: true
    }
  }

  render () {
    return (
      <div className="ag-theme-material">
        <AgGridReact
          containerStyle={{height: '400px', width: '700px'}}
          columnDefs={this.columns}
          rowData={data}
          treeData={true}
          getDataPath={this.getDataPath}
          autoGroupColumnDef={this.autoGroupColumnDef}
          enableGroupEdit={true}
        />
      </div>
    );
  }
}

export default App;

In this example, we enabled cell rendering, column locking, and cell editing. For cell rendering, there is a new “email” column that uses the cellRenderer to return a clickable link. The first column showing the tree icons is also pinned to the left so you can scroll to see the other columns, yet always see who the data belongs to. To enable cell editing, we added editable config to both the “job title” and the “tree” column. It will render the default text editor on double-click. To enable double-click editing, we had to prevent the tree from expanding the node on double-click using the enableGroupEdit prop.

Ext JS to React: Tree, Advanced

You can review the sample code on the Git repo.

Conclusion

Just as we used ag-Grid to create a grid matching Ext JS’s grid, we can use ag-Grid to match Ext JS’s tree as well. Once again, we see that the transition from Ext JS to React isn’t as scary as it first seems. The tree we used here isn’t free. However, ag-Grid’s enterprise pricing does allow single licenses and comes with a two-month free trial.

Have you used a grid or tree component in React that you love? As always, we’d like to hear from you! Please feel free to share any resources you’ve discovered for tabular / hierarchical data using the comments below!

Posted in Application Development
Share this

Seth Lemmons

Seth Lemmons is a Senior Front End Engineer at Modus Create. Seth has devoted several years to learning Ext JS. He has spent the last 10 years building and supporting web applications with an eye for excellent user experience. Outside of work and a young family Seth has very little free time to just do what he wants. But, if he did have some extra time he'd kinda be into learning vector illustration. And someday he hopes to play video games again.
Follow

Related Posts

  • React Landing
    Ext JS to React: Migration to Open Source

    Worried about Migrating from Ext JS? Modus has the Answers Idera’s acquisition of Sencha has…

  • Ext JS to React: FAQ
    Ext JS to React: FAQ

    This is part of the Ext JS to React blog series. React is Facebook's breakout…

Want more insights to fuel your innovation efforts?

Sign up to receive our monthly newsletter and exclusive content about digital transformation and product development.

What we do

Our services
AI and data
Product development
Design and UX
IT modernization
Platform and MLOps
Developer experience
Security

Our partners
Atlassian
AWS
GitHub
Other partners

Who we are

Our story
Careers
Open source

Our work

Our case studies

Our resources

Blog
Innovation podcast
Guides & playbooks

Connect with us

Get monthly insights on AI adoption

© 2025 Modus Create, LLC

Privacy PolicySitemap
Scroll To Top
  • Services
  • Work
  • Blog
  • Resources
    • Innovation Podcast
    • Guides & Playbooks
  • Who we are
    • Our story
    • Careers
  • Let’s talk
  • EN
  • FR