Digital Transformation in HealthCare Solution

Tech Talk

MobX State Tree (MST) - State Management

30 MAY 2021

Hello Developers, Everyone uses various State Management library on their Application, many of us already use Redux, Redux Saga, Redux Rematch. Today we will explore MobX which is the most popular Redux alternative. MobX State Tree (MST) is the powerful state management library which you can use from small to enterprise grade applications and it’s very simple to plug & play. I will take you from core concept to component level integration, So let’s continue,

What will we cover?

  • What is MobX-State-Tree?
  • Why should I use MobX-State-Tree?
  • MobX-State-Tree Installation
  • Getting Started - MobX Entity
  • Creating Model
  • Creating Model Instance
  • Meeting Types
  • Modifying Data
  • Snapshot
  • Snapshot to Model
  • Getting to the UI
  • Improving Render Performance
  • Computed Properties
  • References

What is MobX-State-Tree?

MobX-State-Tree (MST) is a reactive state management library. It is a container system built on MobX.

MobX - State Management Engine and MobX-State-Tree gives you a structure which has type + state to store your data. MST is most preferable from Small to Enterprise grade application where code & functionality is going to scale periodically. Compare to Redux MST offer powerful performance and less lines of code.

MobX supports an array of features for a modern state management system and everything in one package MobX, not more extra dependency.

Why should I use MobX-State-Tree?

MST have many props compare to other state management, Lets’ check few of them,

  • MST offers great compatibility with React Native, ReactJS, VueJS, AngularJS and more JavaScript apps.
  • Instead of messy code everywhere in the app, MST gives centralized stores to quick access and exchange data.
  • Encapsulation - Your data can’t be modified by outside, It can be modified in “actions”. So it’s easy to access but secure from outside access.
  • Runtime type checking - help you to write clean code and prevent users from assigning wrong data to a tree.
  • Whatever you change in the State is tracked and you can create a snapshot of your state at any time.

MobX-State-Tree Installation

As we discussed earlier MobX is State Management and MobX-State-Tree give you structure to store your data. So we need to install mobx, mobx-state-tree.

NPM: npm install mobx mobx-state-tree --save

Yarn: yarn add mobx mobx-state-tree

Let’s create react app,

npx create-react-app todo-app

Now, let’s install dependency,

npm install mobx mobx-state-tree mobx-react-lite

Run ToDo App,

npm run start

Getting Started - MobX Entity

Let’s start by creating a ToDo application. ToDo application have two entities Task and User. Task entity have two attributes, taskName - name of task, taskStatus - to identify tasks completed or not. User entity have two attributes, userID - id of User, userName - name of User.

So, our entities will looks like something,

Task

  • taskName
  • taskStatus

User

  • userID
  • userName

Creating Model

Tree = Type + State - Each tree has a shape (type information) and state (data). Create model with types.model

Creating Model Instance

Simply create instance by calling .create()

Meeting Types

MobX checks runtime type checking, helps developers to identify wrong data passed in argument. This is very helpful while multiple developers are involved in large scale application.

Here, You will get an error like, 95 is not assignable to type boolean, as you have take taskStatus as boolean, so you can’t pass integer data type.

The types namespace are derived from the MST package, You can check lots of widely usage types like array, map, maybe, union and many more. You can check various types available in MST.

Now, It’s time to create a root model, let’s combine Task and User model.

Note - If you are not passing default model value on .create() then you must specify default value of in second argument of types.optional(arg1, arg2).

Modifying Data

MST - Tree node only modified in actions only.

Have you noticed self, - self object constructed when an instance of your model is created. It’s this-free, you can access it using self.

Snapshot

Let’s say you want to see the value stored in your state, which means take a look at a snapshot. It's simple using getSnapshot(). Every Time when you update your state and want to check if changes are reflected in the state, you can check using getSnapshot().

To listen to state change you an use this onSnapshot(store, snapshot => console.log(snapshot))

Snapshot to Model

In the previous step we see we retrieved a snapshot from the model. But Is that possible to restore the model from the snapshot? Yes, it's simple. Let’s see how.

Before that I would like to relate this process with Redux, so you quickly understood. In Redux we have Reducer where we have State - and we initialize State variables with default values, like users: [], tasks: []). Now first time when user open application, we haven’t any snapshot/empty store, so store will refill using model’s default value (default state value). After interaction with the application you have updated values in store. When you come back next time, it will fetch data from the store and refill your model/state. This same process we are going to do here.

In MobX we can achieve this using two different ways, First - by passing default store value, Second - passing store and default store value (snapshot value).

Getting to the UI

Now, it’s time to work with the UI, to connect the MST store to React Component we required mobx-react-lite. We are going to use an observer - name it self say everything. It’s simple, it observe store and updates React components/ Render React components whenever anything changed in the store.

Improving Render Performance

In Previous steps we have rendered Tasks - for each task we have given the option to mark it complete. Now, everytime we check/uncheck the task our UI will render, because we have added an observer. It’s observer duty to update components when anything updates on the store. So, how to avoid this re-rendering situation. It’s simple let's see it.

We have separate business logic for TaskView, Note - we have added an observer in TaskView. So when anyone changes TaskStatus Check/UnCheck, only TaskView will be rendered. AppView only re-render in a case when a new task is added or existing task deleted.

Computed Properties

Till previous steps we are showing Tasks added by User. What I need to do, to show the count of Completed Tasks and Pending Tasks? It’s simple with MobX, add getter property in our model by calling .views, it will count how many Tasks completed and pending. Let’s see the code.

References

Now, it’s time to assign a User for each Task in Tasks. For this we need to tell MST which is the unique attribute (primary key in db language) in each User model instance. You can implement it using types.identifier type composer.

Now we need to define a reference to the Task Model. It’s simple - you can do it using types.reference(User). Many times it’s a circular reference, so to resolve it we need to use types.late(() => User). It may be possible User entry found null, to resolve that we need to use type.maybe(...), So finally let’s see how code looks like,

We have covered almost all required topics from MobX-State-Tree. MobX provided few sample example, download ToDoMVC - app using React and MST and Bookshop - app with references, identifiers, routing, testing etc.

Thanks for reading Blog!

Want to receive Tech Articles!

Get tech aricles directly in your inbox! Share your email with us and receive tech articles as instant as we publish!

KPIENG

KPITENG

DIGITAL TRANSFORMATION

Want to talk about your project?

  • INDUSTRY
  • E-Commerce & Shopping
  • Healthcared & Fitness
  • Banking & Finance
  • Education
  • Logistics & Distribution
  • Social Networking
  • Real Estate
  • Food & Restaurant
  • On-Demand Services
  • Media
  • IT & Telecom
  • Productivity

Want to talk about your project?

© 2021 KPITENG, all rights reserved