Enterprise-ready Redux with Umi and Dva

No Comments

React is successful because it came from a practical need out of Facebook, maybe the biggest and most complex website in existence.

While React has thrived as a view layer, the ecosystem around state management seems to be more of an academic endeavour and there doesn’t appear to be a clearly proven best practice.
While Redux has become the most popular central state management solution, you still have to select a solution for asynchronous events and it it’s often very verbose. Managing your files is another topic that is unclear.
This fragmented ecosystem results in a steep learning curve for new developers joining the project. Also, many different opinions and decisions have taken a toll.

These questions are especially relevant for companies like codecentric. We basically have these problems in every new project we take on. At the same time, our customers have high expectations when it comes to frontend development.

While FAANG companies are always on our radar, China also has technology behemoths with a lot of resources and problems they have to solve for themselves.

One year ago the biggest fintech company worldwide Ant Financial published Umi, which, by their own account, they use extensively themselves.

Umi is the basic frontend framework of Ant Financial, and has served 600+ applications directly or indirectly, including Java, Node, mobile apps, Hybrid apps, pure front-end asset apps, CMS apps, and more. Umi has served our internal users very well and we hope that it can also serve external users to the same extent.

When you analyse the maturity of the toolset and the code, this appears to be true. Basically all requirements big companies have for a frontend appear to have an existing solution.

There is still a lot of Chinese around their documentation and examples, but all the essential parts are available in English and many things are self-explanatory.
It’s also not a reinvention of the wheel: it uses proven methods and libraries which are all documented in English.

Let’s get into it step by step.

Umi’s routing is inspired by Next.js, which equates folder paths with routes.
This is very useful because you find everything immediately (one of the elegant parts of php).

Let’s get started with the basic commands from the Umi site:
(if you want scaffolding with plugins immediately you can also use scaffolding with “yarn umi create”.)

# Install deps
$ yarn global add umi # or npm install -g umi
 
# Create application
$ mkdir myapp && cd myapp
 
# Create page
$ umi generate page index
 
# Start dev server
$ umi dev

So now localhost  should already have opened and show “Page index”.

That’s how simple the tool is, you have basically one folder and one file and it works.
Even create-react-app generates half a dozen tools and packages with the possibility to “eject”.

Umi even supports Typescript out of the box, just change the file ending.

The frameworks has an agreed convention for folders.

Lets’ do something practical and load some data with a mock:

Create a file with a folder pages/users/$id.js.
The $ sign is used for dynamic parameters, so we can access the id of the user.
Now add the following function to test the routing for the ID 1:

Didn’t I introduce a nice organisation for Redux? The solution is a plugin for Umi called Dva.
The website is still only in Chinese, but it’s not very complicated and the integration with Umi is documented here.

Let’s start by installing the plugin:

yarn add umi-plugin-react dva

Now let’s add a file config/config.js and integrate the plugin:

export default {
  plugins: [
    [
      'umi-plugin-react',
      {
        dva: {
          immer: true
        }
      }
    ],
  ],
};

You can add a global model, but mostly you want a feature only used on your subpage.
Why not put it right where it is used? Let’s add a file under the path pages/users/model.js.
One interesting thing about the Umi ecosystem is that there is always a way to scale up.
You can create a models folder with individual files in pages/users when model.js would become too big.

Let’s add a reducer and an effect we can use from the $id.js

const users = {
    "1": "Adam",
    "2": "Eve"
};
 
function getUserName(id) {
    return users[id]
}
 
export default {
    namespace: 'user',
    state: [],
    reducers: {
        set(state, { payload: name }) {
            return {
                name
            };
        },
    },
    effects: {
        *load({ payload: id }, { put, call }) {
            const name = yield call(getUserName, id);
            yield put({ type: 'set', payload: name });
        },
    }
};

Let’s extend pages/users/$id.js to integrate the model file.

Now you are able to click the button, then the effect load gets triggered. Afterwards the name is set for the state and can be set with Redux in the connect function with MapStateToProps like we are used to.

That’s it. The user folder is encapsulated, there is no unnecessary code and we are only beginning to scratch the surface of what Umi can do.

We also know that it will scale from here, otherwise Ant couldn’t have built so many projects with it.
Also there is no lock-in or magic at play, the project can be migrated back into a different React/Redux setup.

What Umi and especially Dva needs now is more English documentation, some things are not immediately clear, especially for new users.
I don’t understand Chinese unfortunately, but there is enough for me right now to use it today.

If you are looking for a long-term and scalable frontend architecture, you should definitely consider Umi.
It’s also MIT-licensed and React/Redux has already enormous developer mindshare.
Even without broader adoption, further support is secured by the huge dependence of Ant Financial on it.

Severin is a Full Stack – IT Consultant with an emphasis on modern Single Page Applications.

Post by Severin Kistner

Frontend

How React Makes Web Development Scalable

More content about Frontend

Comment

Your email address will not be published. Required fields are marked *