MobX State Tree (MST) — State Management
MobX State Tree is powerful state management library works with small to enterprise grade application.
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 to Model
- Getting to the UI
- Improving Render Performance
- Computed Properties
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,
- 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.
As we discussed earlier MobX is State Management and MobeX-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,
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()
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).
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.
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 MobeX 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 mobex-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 lts 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.
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.
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 MobeX-State-Tree. MobeX provided few sample example, download ToDoMVC — app using React and MST and Bookshop — app with references, identifiers, routing, testing etc.
Thanks for reading Blog!
Thanks for reading Article! || Read More Technical Articles
KPITENG | DIGITAL TRANSFORMATION
www.kpiteng.com || firstname.lastname@example.org