My MobX findings

For one of my React Native projects, I started to use MobX as a state management tool. I have used Redux before, but I have to say that MobX feels a lot simpler in terms of updating and managing state via code.

Mobx is using an observer pattern to signal state changes and on every change, it will send a message to every subscriber that is observing some observable variables.

Changing the state is as easy as just changing a property on your model. All subscribers of the property will be updated. This reactive model can be used in any JS framework or even in plain JS.

An example store

class GameStore {
  @observable
  loading: boolean = false;
  @observable
  games: Game[] = [];

  @action.bound
  async addGame(game: Game) {
    runInAction(() => {
      this.games.unshift(game);
    });
  }

  @action.bound
  removeGame(game: Game) {
    runInAction(() => {
      this.games = this.games.filter(g => g !== game);
    });
  }
}

This is the simplified version of my GameStore. It has a few actions and some observable properties.

Best practices for using MobX

While using MobX I follow to the following (best) practices:

Use many specific stores

In Redux you are used to having only one store for all your application state. MobX suggests to have as many stores as you want. So in my application, I have a GameStore, a NoteStore, a LocationStore, and a UserStore. A store is nothing more than a class holding reference to the piece of state that you want to manage.

So my GameStore has a simple Array of Game models and exposes some actions like addGame() or removeGame() that just push or pop the game on the internal Array. MobX takes care of updating all the observers.

Change state only via actions on the model

Because changing state in MobX is so easy, you could do that easily in your view components. However, this is, in general, a bad idea as it becomes hard to track where in your application the state is changed. A better practice is to define actions on your model. Actions are simple methods on your model that define behavior. So when I want to change the name of a user, I could simply set the name property of my User model in the Profile view. But instead, I will define a method called changeName() on my User model and just call that. This way we have all the state changes nicely together in our model.

A pattern I am just figuring out is to pass the GameStore to my Game model so that I can just call remove() on my model. This remove action will then tell the GameStore to remove itself from the list of games. This makes my code really easy to read.

About autorun

MobX makes it easy to react to state changes in your model by using reactions. Autorun is one of them. Reactions make it easy to observe some state and react to it. At the moment I am working on using autorun to implement a sync mechanism with a remote server. So when a game is changed, it is updated in the local database and in the API.

Conclusion

I really like this reactive model of MobX. It takes a lot less code to change the state compared to Redux and it’s reactions make it really easy to react to changes. I am sure there will be good reasons for when to use Redux or when to use MobX and that MobX probably has some drawbacks as well. I did not find any yet, but I will be looking out for them in the future when I come further in the development of the project.

https://mobx.js.org/README.html