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: Basic Grid

Published on February 13, 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.

The grid is the defining component of the Ext JS framework. When we think of Ext JS, the first image that comes to mind is its grid and for good reason. Ext JS’s grid is unmatched in features and quality. However, depending on the needs of your application, you may consider writing your own grid. You may be surprised at how easy it is with React.

Sample data generator

Ext JS relied heavily on its data package for its views consuming that data. While a mature data module is great for complex modeling, for most views we can just furnish the bits that are needed. For this and subsequent grid blogs, we will use the following data module:

const companies = [
  'Airconix', 'Qualcore', 'Hivemind', 'Thermolock', 'Sunopia'
];
const firstNames = [
  'Raymond', 'Vernon', 'Dori', 'Jason', 'Rico'
];
const lastNames = [
  'Neal', 'Dunham', 'Seabury', 'Pettey', 'Muldoon'
];

const random = (array) => array[ Math.floor(Math.random() * array.length) ];

const dataSync = ({ num = 50, startRow = 0, total = 50000 } = {}) => {
  const data = [];

  for (let i = 0; i < num; i++) {
    const company = random(companies);
    const first = random(firstNames);
    const last = random(lastNames);

    data.push({
      id: i + startRow,
      name: `${first} ${last}`,
      company,
      email: `${first.toLowerCase()}.${last.toLowerCase()}@${company.toLowerCase()}.com`
    });
  }

  return { data, total };
};

const dataAsync = async ({ delay = 500, num, startRow, total } = {}) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(dataSync({ num, startRow, total }));
    }, delay);
  });
};

export default dataSync;
export { dataAsync };

Note: In the data module above, you’ll see that there are two export statements. The export default dataSync statement indicates that any class importing from the file with this module will receive the dataSync object. The name of the object imported can be whatever suits the importing class as we see in the import getData from './data' example statement below. The export { dataAsync } statement enables another class to request the dataAsync function by name. For more information on the ECMAScript 2015 (ES6) export convention, checkout the named export and default export sections on the MDN export guide.

Lightweight React grid class

We’ve long heard that people love Ext JS’s grid, but sometimes they need a lightweight version. With Ext JS, there simply is no lightweight grid. It has to support so many features yet come to an agreement regarding the minimal functionality people would expect. If you want to display data in a tabular format, but don’t need all the functionality under the sun, you can easily write a simple React component to be just that:

import React, { Component } from 'react';
import getData from './data';

const { data } = getData();

class Grid extends Component {
  render () {
    const { className } = this.props;

    return (
      <table className={`grid ${className ? className : ''}`}>
        <thead>
          <tr>
            <th>Name</th>
            <th>Company</th>
            <th>Email</th>
          </tr>
        </thead>
        <tbody>
          {
            data.map(item => (
              <tr key={item.id}>
                <td>{item.name}</td>
                <td>{item.company}</td>
                <td>{item.email}</td>
              </tr>
            ))
          }
        </tbody>
      </table>
    );
  }
}

export default Grid;
Ext JS to React: Basic Grid, Lightweight Grid

This component shows our data in 3 columns in a table that is as lightweight as you can get. The headers will be bolded automatically as the default styling of the <th> nodes. With a few additional simple styles, you can set the background color on the header along with row and column lines. By using a small React component class and a few styles rules, you now have a lightweight grid!

Sorting the React grid

Currently, we have a lightweight grid that simply displays our data. If the data arrives unsorted or you want to allow users to sort a column, then we need to add sorting functionality to the grid. To enable sorting, we’ll need to make a couple of changes:

  1. Add an onClick listener to the headers in order to set the sort state when a user clicks on the header. This will also toggle the existing sort state between ascending and descending.
  2. Display sort status in the headers
  3. Sort the data before creating the grid rows

The updated grid would then look like:

import React, { Component } from 'react';
import getData from './data';

const { data } = getData();

class Grid extends Component {
  state = {}

  render () {
    const { className, data } = this.props;
    const { sort } = this.state;

    return (
      <table className={`grid ${className ? className : ''}`}>
        <thead>
          <tr>
            <th onClick={this.handleHeaderClick.bind(this, 'name')}>
              Name{this.getSort('name', sort)}
            </th>
            <th onClick={this.handleHeaderClick.bind(this, 'company')}>
              Company{this.getSort('company', sort)}
            </th>
            <th onClick={this.handleHeaderClick.bind(this, 'email')}>
              Email{this.getSort('email', sort)}
            </th>
          </tr>
        </thead>
        <tbody>
          {
            this.sortData(data, sort).map(item => (
              <tr key={item.id}>
                <td>{item.name}</td>
                <td>{item.company}</td>
                <td>{item.email}</td>
              </tr>
            ))
          }
        </tbody>
      </table>
    );
  }

  getSort (dataIndex, sort) {
    return sort && sort.dataIndex === dataIndex ?
      ` (${sort.direction})` :
      null;
  }

  handleHeaderClick = (dataIndex) => {
    const { sort } = this.state;

    const direction = sort && sort.dataIndex === dataIndex ?
      (sort.direction === 'ASC' ? 'DESC' : 'ASC') :
      'ASC';

    this.setState({
      sort: {
        dataIndex, direction
      }
    });
  }

  sortData (data, sort) {
    if (sort) {
      const { dataIndex, direction } = sort;
      const dir = direction === 'ASC' ? 1 : -1;

      return data.slice().sort((A, B) => {
        const a = A[ dataIndex ];
        const b = B[ dataIndex ];

        if (a > b) {
          return 1 * dir;
        }

        if (a < b) {
          return -1 * dir;
        }

        return 0;
      });
    }

    return data;
  }
}

export default Grid;

React grid class instantiated

To instantiate the Grid, we pass the data prop with the data set from our example above:

import React, { Component } from 'react';
import Grid from './Grid';
import getData from './data';

const { data } = getData();

class App extends Component {
  render() {
    return (
      <Grid data={data} />
    );
  }
}

export default App;
Ext JS to React: Basic Grid, Sorted Grid

Now we have a very lightweight, sortable grid and all in less than 90 lines of code!

Conclusion

You may have never thought about writing your own grid when coming from Ext JS. If all you need is a lightweight grid with optional sorting, try writing your own with React. While you will likely require a more feature-rich grid selectively throughout your application, it’s a great idea to start with vanilla React. This will help your understanding of how React works versus Ext JS. In the next blog, we will look at a third-party grid component and how to use selection models like you would with Ext JS.

Posted in Application Development
Share this

Mitchell Simoens

Mitchell Simoens is a Senior Front End Engineer at Modus Create. Mitchell has spent the last 10 years working with Ext JS including developing core functionality, Sencha Fiddle and (I hope your insurance covers blown minds) supporting the online community with over 40,000 posts on the Sencha Forums. Before working with Ext JS, Mitchell used Perl and PHP but loves spending time with Node JS for today's needs. When not working, you can find Mitchell relaxing with his wife and daughter, or developing his talents as an amateur furniture maker.
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: Selection Model
    Ext JS to React: Selection Model

    This is part of the Ext JS to React blog series. You can review the…

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