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: Load, Sort and Filter Data with React

Published on April 12, 2018
Last Updated on January 29, 2023
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.

In previous articles on List and Grid, we used local data exclusively. In this article, we are going to look at tackling some basic remote data loading in order to transition from Ext JS’ strong data package. There are many different means of loading remote data depending on your server. In this article we will focus on loading JSON data using the native Fetch API.

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.

Sample Remote Data

For the examples in this article, we’ll use the following data (located at {appRoot}/public/data.json for those following along with the starter app):

[{
  "id": 0,
  "name": "Vernon Dunham",
  "company": "Qualcore",
  "email": "vernon.dunham@qualcore.com"
}, {
  "id": 1,
  "name": "Dori Neal",
  "company": "Sunopia",
  "email": "dori.neal@sunopia.com"
}, {
  "id": 2,
  "name": "Rico Muldoon",
  "company": "Airconix",
  "email": "rico.muldoon@airconix.com"
}, {
  "id": 3,
  "name": "Jason Neal",
  "company": "Qualcore",
  "email": "jason.neal@qualcore.com"
}, {
  "id": 4,
  "name": "Rico Pettey",
  "company": "Thermolock",
  "email": "rico.pettey@thermolock.com"
}, {
  "id": 5,
  "name": "Raymond Seabury",
  "company": "Airconix",
  "email": "raymond.seabury@airconix.com"
}, {
  "id": 6,
  "name": "Dori Pettey",
  "company": "Hivemind",
  "email": "dori.pettey@hivemind.com"
}, {
  "id": 7,
  "name": "Vernon Neal",
  "company": "Qualcore",
  "email": "vernon.neal@qualcore.com"
}, {
  "id": 8,
  "name": "Jason Neal",
  "company": "Qualcore",
  "email": "jason.neal@qualcore.com"
}, {
  "id": 9,
  "name": "Vernon Muldoon",
  "company": "Airconix",
  "email": "vernon.muldoon@airconix.com"
}, {
  "id": 10,
  "name": "Vernon Seabury",
  "company": "Hivemind",
  "email": "vernon.seabury@hivemind.com"
}, {
  "id": 11,
  "name": "Dori Neal",
  "company": "Airconix",
  "email": "dori.neal@airconix.com"
}, {
  "id": 12,
  "name": "Raymond Pettey",
  "company": "Airconix",
  "email": "raymond.pettey@airconix.com"
}, {
  "id": 13,
  "name": "Rico Muldoon",
  "company": "Qualcore",
  "email": "rico.muldoon@qualcore.com"
}, {
  "id": 14,
  "name": "Vernon Seabury",
  "company": "Sunopia",
  "email": "vernon.seabury@sunopia.com"
}, {
  "id": 15,
  "name": "Rico Pettey",
  "company": "Airconix",
  "email": "rico.pettey@airconix.com"
}, {
  "id": 16,
  "name": "Jason Dunham",
  "company": "Sunopia",
  "email": "jason.dunham@sunopia.com"
}, {
  "id": 17,
  "name": "Vernon Neal",
  "company": "Qualcore",
  "email": "vernon.neal@qualcore.com"
}, {
  "id": 18,
  "name": "Jason Pettey",
  "company": "Thermolock",
  "email": "jason.pettey@thermolock.com"
}, {
  "id": 19,
  "name": "Vernon Dunham",
  "company": "Thermolock",
  "email": "vernon.dunham@thermolock.com"
}]

Fetching Remote Data

Since React doesn’t have a data store, you may be worried about creating one yourself. Ext JS’s data stores were powerful and flexible, however, they are very feature-heavy and may be overkill for simple views. The action of loading JSON data using the Fetch API is actually extremely simple. Let’s take a look at a simple list component that loads its data remotely. While the loading is occurring we’ll show loading text:

class List extends Component {
  state = {}

  componentDidMount () {
    fetch('/data.json')
      .then(res => res.json())
      .then(this.onLoad);
  }

  parseData (response) {
    return response.data;
  }

  onLoad = (data) => {
    this.setState({
      data: this.parseData(data)
    });
  }

  render () {
    const { data } = this.state;

    return data ?
      this.renderData(data) :
      this.renderLoading()
  }

  renderData (data) {
    if (data && data.length) {
      return (
        <div>
          {
            data.map(item => (
              <div key={item.id}>
                <a href={`mailto:${item.email}`}>{item.name}</a> {item.company}
              </div>
            ))
          }
        </div>
      );
    } else {
      return <div>No items found</div>
    }
  }

  renderLoading () {
    return <div>Loading...</div>
  }
}

List Class Explained

The most important piece here is the componentDidMount. This React lifecycle method is where you would kick off the data loading and here we set the data (nested in a data root property) to the list’s state. We execute the parseData method when setting the state, you’ll see why we do this in a little bit. In the render method, we check if data is present. If it is, we render the data in the renderData method. If there isn’t any data, then we render some loading text via the renderLoading method. The loading text here is a simple div node, but could be something more visual for the user like we showed in the Floating Components article.


NEW RESEARCH: LEARN HOW DECISION-MAKERS ARE PRIORITIZING DIGITAL INITIATIVES IN 2024.

Get Report


This code is very straightforward and you can see how simple it was to implement loading remote data using the Fetch API and we didn’t need to use a data store like we would with Ext JS. This means performance should be higher and a production build would be smaller. Of course, if we needed to load something other than a response the Fetch API natively supports, we’d have to replace it with some proxy/reader setup (think SOAP, XML, etc.).

Remote Data Example

import React from 'react';
import List from './List'

export default () => <List />;
Ext JS to React: Load, Sort and Filter Data with React - Remote Data Example

You can review the sample code on the Git repo.

Data Sorting Utility Functions

In order to sort data locally, we can add our sorting code in the parseData method. Once again, we aren’t in an environment like Ext JS that has functionality built into data stores. So we have to rely on native JavaScript here and therefore use Array’s sort method. Since sorting is likely going to be used in multiple places around an application, we can create a utility file that will handle sorting in an abstract way. You can save a Sort.js file within the src/util/ directory (depending on your React app setup) with this abstract code:

const dirMap = {
  // greater-than
  gt: { asc: 1, desc: -1 },
  // less-than
  lt: { asc: -1, desc: 1 }
};

const doSort = (A, B, property, direction = 'ASC') => {
  const a = A[ property ];
  const b = B[ property ];

  if (a < b) {
    return dirMap.lt[ direction.toLowerCase() ];
  }
  if (a > b) {
    return dirMap.gt[ direction.toLowerCase() ];
  }
  return 0;
}

const createSorter = (...args) => {
  if (typeof args[0] === 'string') {
    args = [
      {
        direction: args[1],
        property: args[0]
      }
    ];
  }

  return (A, B) => {
    let ret = 0;

    args.some(sorter => {
      const { property, direction = 'ASC' } = sorter;
      const value = doSort(A, B, property, direction);

      if (value === 0) {
        // they are equal, continue to next sorter if any
        return false;
      } else {
        // they are different, stop at current sorter
        ret = value;

        return true;
      }
    })

    return ret;
  }
}

export { createSorter };

Sorted List Class

When we want to sort data, we can use the createSorter function and pass the generated function to the array’s sort function. The beginning of our List would then look like:

import React, { Component } from 'react';
import { createSorter } from './util/Sort';

class List extends Component {
  state = {
    sorters: this.props.sorters
  };

  static defaultProps = {
    sorters: [{
      property: 'name'
    }, {
      property: 'company'
    }]
  };

  componentDidMount() {
    fetch('/data.json')
      .then(res => res.json())
      .then(this.onLoad);
  }

  parseData(data) {
    const { sorters } = this.state;

    if (data && data.length) {
      if (Array.isArray(sorters) && sorters.length) {
        data.sort(createSorter(...sorters));
      }
    }

    return data;
  }

  onLoad = data => {
    this.setState({
      data: this.parseData(data)
    });
  };

  render() {
    const { data } = this.state;

    return data ? this.renderData(data) : this.renderLoading();
  }

  renderData(data) {
    if (data && data.length > 0) {
      return (
        <div>
          {data.map(item => (
            <div key={item.id}>
              <a href={`mailto:${item.email}`}>{item.name}</a> {item.company}
            </div>
          ))}
        </div>
      );
    } else {
      return <div>No items found</div>;
    }
  }

  renderLoading() {
    return <div>Loading...</div>;
  }
}

export default List;

Sorting Example

import React from 'react';
import List from './List'

export default () => <List />;
Ext JS to React: Load, Sort and Filter Data with React - Sorting Example

Now when the data is loaded, the data will automatically be sorted using the sorters property within the parseData. Now you can see why we split this out into its own method. Here we set a default sorters array in the static defaultProps but the sorters property could be set when instantiating the List class:

const sorters = [{ property: 'name', direction: 'DESC' }]
<List sorters={sorters} />

To do remote sorting, you would have to append a URL parameter to the URL passed to the fetch function and do not add the sorting code to parseData:

  componentDidMount () {
    const { sorters } = this.state

    fetch(`/data.json?sort=${JSON.stringify(sorter)}`)
      .then(res => res.json())
      .then(this.onLoad.bind(this))
  }

You can already start to envision how this could be set as a prop on the List class or even on the List’s state to sort either locally or remotely. The difference is whether you pass the sort information as a URL parameter or if you use a sort function locally.

You can review the sample code on the Git repo.

Data Filtering Utility Functions

The other common functionality of an Ext JS data store is to filter data. Like we did with the Sort module, we can create a Filter.js within the src/util/ directory that can handle the filtering in an abstract way:

const doFilter = (item, filter) => {
  let { value } = filter;

  if (!(value instanceof RegExp)) {
    value = filter.value = new RegExp(value, 'i');
  }

  return value.test(item[ filter.property ]);
}

const createFilter = (...filters) => {
  if (typeof filters[0] === 'string') {
    filters = [
      {
        property: filters[0],
        value: filters[1]
      }
    ];
  }

  return item => filters.every(filter => doFilter(item, filter));
};

export { createFilter };

Filtered List Class

To use the createFilter function, we want to handle filtering in the renderData method of our List class. The reason to do this within the renderData (render phase) is we want to keep the data we got remotely as it is. This is so if we want to be able to change filters only in the client, we have the entire data array and we can apply filters when rendering. This way, setting the state will automatically pick up any filter change without you having to do anything in the List. The List class should now look like:

import React, { Component } from 'react';
import { createFilter } from './util/Filter';
import { createSorter } from './util/Sort';

class List extends Component {
  state = {
    filters: this.props.filters,
    sorters: this.props.sorters
  }

  static defaultProps = {
    filters: [{
      property: 'name',
      value: 'dori'
    }, {
      property: 'company',
      value: 'a'
    }],

    sorters: [{
      property: 'name'
    }, {
      property: 'company'
    }]
  }

  componentDidMount () {
    fetch('/data.json')
      .then(res => res.json())
      .then(this.onLoad);
  }

  parseData (data) {
    const { sorters } = this.state;

    if (data && data.length) {
      if (Array.isArray(sorters) && sorters.length) {
        data.sort(createSorter(...sorters));
      }
    }

    return data;
  }

  onLoad = (data) => {
    this.setState({
      data: this.parseData(data)
    });
  }

  render () {
    const { data } = this.state;

    return data ?
      this.renderData(data) :
      this.renderLoading();
  }

  renderData (data) {
    if (data && data.length > 0) {
      const { filters } = this.state;

      if (Array.isArray(filters) && filters.length) {
        data = data.filter(createFilter(...filters));
      }

      return (
        <div>
          {
            data.map(item => (
              <div key={item.id}>
                <a href={`mailto:${item.email}`}>{item.name}</a> {item.company}
              </div>
            ))
          }
        </div>
      );
    } else {
      return <div>No items found</div>;
    }
  }

  renderLoading () {
    return <div>Loading...</div>;
  }
}

export default List;

Filtering Example

import React from 'react';
import List from './List'

export default () => <List />;
Ext JS to React: Load, Sort and Filter Data with React - Filtering Example

The list will now use the default filters when rendering the data. Sorting will happen when the data is loaded and the filtering will happen when the data is being rendered.

Like sorting, you can also provide filters as a prop:

const filters = [{ property: 'name', value: 'rico' }]
<List filters={filters} />

You can review the sample code on the Git repo.

Conclusion

Loading remote data and sorting and filtering that data is simple using native JavaScript. Ext JS initially supplied the functionality prior to native array sorting and filtering. However, browsers have now been supporting these functions since IE9. Ext JS does have several built-in proxies and readers to handle different transports and formats so if you need to deal with something more than JSON, you’ll have to provide your own or search npm to see if a pre-built option exists.

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

  • 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…

  • 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…

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