Redux vs MobX without confusion

image

In recent years, I have often used Redux , but recently I have been using MobX as an alternative to state management. Redux alternatives seem to naturally turn into a mess. People are not sure which solution to choose. The problem is not necessarily Redux vs MobX. Whenever there is an alternative, people are curious how best to solve their problem. I am writing these lines to eliminate confusion around Redux and MobX state management solutions.

What will this article be about? First, I want to briefly return to the problem that the state management library solves. In the end, everything will be fine if you just use this.setState () and this.state in React or its variation in another presentation-level library or in a SPA environment. Secondly, I will continue to give you an overview of both solutions, showing consistency and differences. And last but not least, if you already have an application that works with MobX or Redux, I want to tell you about refactoring from one state library to another.

Content:


  1. What problem do we solve?
  2. What is the difference between REDUX and MOBX?
  3. React state learning curve
  4. Recent thoughts on the topic
  5. More resources


What problem do we solve?


Everyone wants to have state management in the application. But what problem does this solve for us? Most people start with a small application and already implement a state management library. Everyone is talking about it, right? Redux! MobX! But most applications do not need ambitious state management from the start. This is even more dangerous because most people will never be confronted with problems such as libraries such as Redux or MobX .

The status quo is currently building a front-end application with components. Components have an internal state. In a growing application, state management can become chaotic with a local state, because:

  • a component must share state with another component
  • a component must modify the state of another component

At some point, it becomes more and more difficult to talk about the state of the application. This becomes a dirty web of state objects and state mutations in your component hierarchy. In most cases, state objects and state mutations are not necessarily associated with one component. They are linked through your component tree, and you must raise and lower the state.

The solution, therefore, is to introduce a state management library such as MobX or Redux. It gives you tools to save your state, change state, and receive state updates. You have one place to search, one place to change, and one place to receive status updates. He follows the principle of a single source of truth.. This makes it easier to reason about changes in your state and conditions, because they separate from your components.

State management libraries such as Redux and MobX often have add-ons for utilities, for example, for Angular they have angular-redux and mobx-angular to give your components access to state. Often, these components are called containerized components, or, to be more precise, related components . From anywhere in your component hierarchy, you can access the state and change it by updating your component to a related one.


What is the difference between REDUX and MOBX?


Before we dive into the difference, I want to tell you about the similarities between MobX and Redux.

Both libraries are used to control state in JavaScript applications. They are not necessarily associated with a library such as Angular. They are also used in other libraries such as ReactJs and VueJs.

If you choose one of the state management solutions, you will not run into a vendor lockout. You can switch to another state management solution at any time. You can upgrade from MobX to Redux or from Redux to MobX. Later I will show you how this happens.

Redux designed by Dan Abramov and Andrew Clark is a derivative of the Flux architecture. Unlike Flux, it uses one repository over several to maintain state. In addition, instead of a dispatcher, it uses pure functions to change state. If you are not familiar with the flow and you are new to state management, do not worry about the last paragraph.

Redux is influenced by the principles of functional programming (FP). FP can be done in JavaScript, but many people come from an object-oriented background, like Java, and have difficulty accepting the principles of functional programming in the first place. This later explains why MobX may be easier to learn as a beginner.

Since Redux includes functional programming, it uses pure functions .
A pure function is a function that receives input, returns output, and has no other dependencies other than the same functions. Such a function always produces the same output with the same input and has no side effects. More details

(state, action) => newState

Your Redux state is unchanged . Instead of mutating, you always return a new state. You do not perform state mutations and are not dependent on object references.


//     Redux,     
function addAuthor(state, action) {
  return state.authors.push(action.author);
}
//       
function addAuthor(state, action) {
  return [ ...state.authors, action.author ];
}

And last but not least, in idiomatic Redux, your state is normalized , like in a database. Entities refer to each other only by id . This is the best practice. Although not everyone does, you can use a library like normalizr to achieve such a normalized state. Normalized state allows you to maintain a flat state and entities as a single source of truth .

{
  post: {
    id: 'a',
    authorId: 'b',
    ...
  },
  author: {
    id: 'b',
    postIds: ['a', ...],
    ...
  }
}



In comparison, Michel Weststratt’s MobX is influenced not only by object-oriented programming, but also by reactive programming. It wraps your state in observable objects. Thus, you have all the features of " Observable " in your state. Data can have simple setters and getters, but observable allows you to receive updates after data changes.

In Mobx, your status is volatile . This way you change the state directly:

function addAuthor(author) {
  this.authors.push(author);
}

In addition, organizations remain in a (deeply) nested data structure with respect to each other. You do not normalize your condition. The condition remains denormalized and embedded.

{
  post: {
    id: 'a',
    ...
    author: {
      id: 'b',
      ...
    }
  }
}

One repository versus several


In Redux, you store all your state in one global repository or in one global state . A single state object is your only source of truth. Numerous gearboxes, on the other hand, allow it to change an unchanging state.

In comparison, MobX uses several repositories. Like Redux reducers, you can apply separation and conquest by technical level, domain, etc. You can store your domain objects in separate repositories, but you can also control the viewing status in your repositories. In the end, you place the state that is most appropriate for your application.

Technically, you can have multiple repositories in Redux as well. No one forces you to use only one. But this is not an advertised use case of Redux. Using multiple repositories runs counter to best practices. In Redux, you want to have one repository that responds through its reducers to global events.

What does the implementation look like?


On Redux, adding the configuration of an application to a global state requires the following lines of code.

const initialState = {
  users: [
    {
      name: 'Alex'
    },
    {
      name: 'Nik'
    }
  ]
};
// reducer
function users(state = initialState, action) {
  switch (action.type) {
  case 'USER_ADD':
    return { ...state, users: [ ...state.users, action.user ] };
  default:
    return state;
  }
}
// action
{ type: 'USER_ADD', user: user };

In MobX, storage will only manage the substate (as the reducer in Redux controls the substate), but you can directly change the state. The @observable annotation allows you to observe state changes.

class userStore{
@observable users = [
    {
      name: 'Nikita'
    }
  ];
}

Now you can call userStore.users.push (user); on the copy of the store. However, it is recommended that state mutations be more explicit through action.

class userStore{
@observable users = [
    {
      name: 'Nikita'
    }
  ];
}
@action addUser = (user) => {
    this.users.push(user);
  }

You can strictly apply it by configuring MobX with configure ({empceActions: true});. Now you can change your state by calling userStore.addUser (user); on the copy of the store.

You have seen how to update state on both Redux and MobX. In Redux, your state is read-only . You can only change state with explicit actions . In contrast, in MobX, state includes reading and writing. You can mutate the state directly without using actions, but you can select explicit actions using the enforceActions configuration.


React state learning curve


Both Redux and MobX are mainly used in React applications. But these are standalone state management libraries that can be used everywhere without React. Their interaction libraries make it easy to combine them with Angular components. These are react-redux for React + Redux and mobx-react for React + MobX . Later I will explain how to use both in the Angular component tree.

In recent discussions, it has happened that people argued about the learning curve in Redux. This often happened in the context of React: people started learning React and already wanted to use state management with Redux. Most people claim that React and Redux themselves have a good learning curve, but both can be overwhelming. Therefore, MobX will be an alternative, because it is more suitable for beginners.

However, I would suggest a different approach for new React users to learn about state management in the React ecosystem. Start learning React with your own local state-management features in components. In a React application, you first learn about the React lifecycle methods and understand how to manage local states with setState () and this.state. I highly recommend this learning path. Otherwise, you will be quickly overwhelmed by the React ecosystem. In the end, along the way you will realize that managing the (internal) state of the components becomes complicated.

Redux or MobX for beginners?


By familiarizing yourself with Angular components and internal state management, you can choose a state management library to solve your problem. After I used both libraries, I would say that MobX can be very convenient for beginners. We've already seen that MobX needs less code, although it does use some magic notes that we don’t need to know about yet.
With MobX, you don't need to be familiar with functional programming. Terms such as immutability may still be foreign.
— , JavaScript. , , - , , MobX.


Redux


As your application grows larger and several developers work on it, you should consider using Redux. By nature, he undertakes to use explicit actions to change state. The action has a type and payload that the gearbox can use to change state. It is very easy for the development team to talk about state changes in this way.

Redux provides you with an entire architecture for managing state with clear limitations. Redux Success Story .

Another advantage of Redux is its use on the server side. Since we are dealing with simple JavaScript, you can send state over the network. Serialization and deserialization of a state object works out of the box. However, this is also possible with MobX.

MobX is less self-confident, but with configure ({empceActions: true}) you can apply more precise restrictions, as in Redux. That's why I would not say that you cannot use MobX to scale applications, but Redux has a clear way to do something. The MobX documentation even says: “ [MobX] doesn't tell you how to structure your code, where to store state, or how to handle events .” The development team would first have to create a state management architecture.

After all, the state management learning curve is not that steep. When we repeat the recommendations, a newbie to React will first learn how to use setState () and this.state correctly . After a while you will understand the problems of using only setState ()to maintain state in the React app. When looking for a solution, you come across state management libraries such as MobX or Redux. But which one to choose? Since MobX is less self-confident, has a smaller template and can be used similarly to setState (), I would recommend giving MobX a chance in small projects. As soon as the application grows in size and increases the number of participants, you should consider applying additional restrictions in MobX or give Redux a chance. I liked using both libraries. Even if you do not use one of them in the end, it makes sense to see an alternative way to manage the state.


Last thoughts


Whenever I read the comments in the Redux vs MobX discussion, there is always one comment: “ Redux has too much standard, you should use MobX instead. I was able to delete XXX lines of code . " The comment may be true, but no one considers a compromise. Redux comes with a lot of templates like MobX because it has been added for specific design constraints. This allows you to reason about the state of your application, even if it is on a larger scale. The whole ceremony associated with the treatment of the state, is not just.

The Redux library is pretty small. Most of the time you only deal with simple JavaScript objects and arrays.. This is closer to vanilla JavaScript than MobX. In MobX, objects and arrays are wrapped in observable objects that hide most of the standard template. It is built on hidden abstractions in which magic occurs, but it is more difficult to understand the basic mechanisms. Redux makes it easier to talk about this with simple JavaScript. This makes it easy to test and debug the application.

In addition, you need to think again about where we came from in the SPA. A bunch of single-page frameworks and application libraries had the same state management problems that were ultimately resolved using a comprehensive stream model. Redux is the successor to this approach.

In MobX, it is again moving in the opposite direction. We again begin to mutate the state directly, without taking advantage of functional programming. For some people, this is again approaching two-way data binding. After some time, people may again encounter the same problems before a state management library such as Redux appears. State management is scattered across the components and ends in clutter.

While on Redux you have an established ceremony for setting things up, MobX is less self-confident. But it would be wise to accept the best MobX experience. People need to know how to organize state management in order to improve their arguments about it. Otherwise, people tend to change state directly in the components.

Both libraries are great. Although Redux is already well established, MobX is becoming a viable alternative to state management.


More resources


comparison of Michel Weststratt - creator of
MobX

All Articles