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: Handling Data with Mobx

Published on April 19, 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.

In a previous article, Handling Application State with Redux, we saw how to use static data to load values into a form and keep the application state in sync as a user edits the form. However, in real world applications, data will often be fetched from a remote server or file. In the following article, we’ll start with the form we built in the previous Redux article and demonstrate how remote can be fetched to populate the form’s fields. We’ll also adjust our previous form to allow form data to be passed in directly making for a more flexible form where data can be furnished or fetched, all with the same form class.

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.

React Form Class with MobX

To evolve the form class from the previous article, we don’t need to add all that much logic. Two major factors go into enabling our form to be populated using a remote source. The first aspect that we’ll look at is located in the componentDidMount method. Let’s take a look at the Form class and then discuss what we’ve added:

import React, { Component } from 'react';
import { action, extendObservable, observable } from 'mobx';
import { inject, observer } from 'mobx-react';
import UserStore from './UserStore';

@inject(({ store }, { user }) => {
  return {
    store,
    user
  };
})
@observer
class Form extends Component {
  static defaultProps = {
    store: new UserStore(),
    @observable user: {}
  }

  @action
  componentDidMount() {
    const { store, user, userId } = this.props;

    if (store.fetchUser && userId) {
      store
        .fetchUser(userId)
        .then(userData => Object.assign(user, userData))
        .catch(console.log);
    }
  }

  render() {
    const { user } = this.props;
    const { renderField, submit } = this;

    return (
      <form>
        {renderField(user, 'name')}
        {renderField(user, 'email', undefined, 'email')}
        {renderField(user, 'phone', 'Phone Number', 'tel')}
        {renderField(user, 'company')}
        {renderField(user, 'department')}
        {renderField(user, 'title')}

        <button onClick={submit}>Submit</button>
        <br />
      </form>
    );
  }

  renderField = (user, name, label = name, type = 'text') => {
    if (user[name] == null) {
      extendObservable(user, {
        [name]: ''
      });
    }

    return (
      <div style={{ marginBottom: '12px' }}>
        <label style={{ textTransform: 'capitalize' }}>
          {label}
          <input
            type="text"
            name={name}
            value={user[name]}
            onChange={this.handleFieldChange}
            style={{ marginLeft: '12px' }}
          />
        </label>
      </div>
    );
  }

  @action.bound
  handleFieldChange(e) {
    const { onChange, user } = this.props;
    const { name, value } = e.target;

    user[name] = value;

    if (onChange) {
      onChange({ [name]: value });
    }
  }

  submit = e => {
    e.preventDefault();

    // do submit
  };
}

export default Form;

React Form Class Explained

In the original Form we apply any passed data object in the user prop to the MobX state object which we then use to populate the form. In our now modified Form’s componentDidMount method we now look for a userId prop. If the userId prop is present (we also check to make sure that the state object has a fetchUser method) we will call store.fetchUser(userId). The object that is returned from fetchUser is set on the global state object’s user node.

MobX Global State Class

The global state object we’re passing to the Form is not only used to host the active user state, but also fetch remote user data for the state object. The UserStore is passed in via the store prop on the Form making the fetchUser method available to any component attached to the global state object. Below is our modified UserStore class:

import { action, observable } from 'mobx';

export default class UserStore {
  @observable user = {};

  @action
  fetchUser (id) {
    return fetch('/user.json')
    .then(resp => resp.json())
    .catch(e => console.log(e));
  }
}

The fetchUser method uses the fetch API to asynchronously read a user.json file to return a sample user object to the form. Any issues in reading the file will be caught by the Promise catch method.

Sample User Data

Below is the sample user object returned from the public/user.json file:

{
  "id": 1,
  "name": "Don Draper",
  "email": "don.draper@scdp.com",
  "phone": "+1 (212) 555-0112",
  "company": "Sterling Cooper Draper Pryce",
  "department": "Marketing",
  "title": "Creative Director"
}

Connecting the MobX State Object to the Application

Passing the global state object to our App is the same as with our previous article:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { Provider } from 'mobx-react';
import UserStore from './UserStore';

ReactDOM.render(
  <Provider store={new UserStore()}>
    <App />
  </Provider>,
  document.getElementById('root'));
registerServiceWorker();

We pass the UserStore class instance to the Provider making it and any of its properties and methods available to the views composed within the app.

Root Application Class

Finally, let’s look at the App class that is the entry point for our app and composes in our Form:

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

export default () => <Form userId={1}/>;
Ext JS to React: Handling Data with Mobx

In this example, we pass a userId prop which prompts the fetching of remote user data. In this example, the value passed isn’t important. In a real world app, the value passed would be used to determine the user record returned from the server.

Wrap Up

MobX makes easy work of sharing data and functions across all views in an application. In the example above we were able to call up the needed form data form a remote file using a method on the UserStore available to any view within the app. Then, by setting the user object back on the UserStore instance, any view within the app has access to the current user data, not just the form that fetched the data initially.

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