Mobx is a state management of library, maybe you are comfortable to some data in the application of management, and have their own good or be fond of state management of the library, but this will not affect your Mobx begin to understand, because these libraries or tools provided to us is the solution to solve the problem of existence has its rationality, namely since Mobx exist, And has been praised by many people, that must have its advantages, based on this reason, we can also spend so a drop of time to get familiar with, may be a great help to us. Based on this idea, I have familiarized myself with Mobx and made a conclusion.

What is Mobx

Mobx is a state management library that does not rely on the view layer framework, unlike Vuex, which is a custom version of Vue. It works well with any view-layer framework, but React works best with it. React already has Redux, so why is there a third party? Redux’s author recommended Mobx, and many people reconfigured the app from Redux to MOBx. This shows that Mobx does have its attractions, and there are plenty of articles in this series without going into the comparison, but it’s a good place to start with a wave of Mobx.

What problem does state management solve

  • Data sharing issues between components

  • Unified management of application state, with components only responsible for data rendering, enhances a maintainable system (this is my opinion, subject to discussion).

The principle of Mobx

Demo1:
import  { observable, autorun } from 'mobx'

const obsObj = observable({
    title: 'hello world'
})

autorun(() => {
    console.log('mobx observal title',obsObj.title)
})

obsObj.title = 'title change'
Copy the code

The output is:

otuput:
mobx observal title: hello world
mobx observal title: title change
Copy the code

Makes an object observable via the Observable method, executes the aurorun function, and automatically executes the Autorun function after the status changes. It can be seen that Mobx itself implements a set of responsive principles. Without reading the source code, it can be roughly known that its implementation uses observer mode. When autorun is executed for the first time, the other party that calls the object attribute intercepts its GET method, and adds this function to its dependency. Autorun is derived from reaction in the original figure, and state is the observable state object after Observable.

Demo2:
import  {observable, autorun, action} from 'mobx'

const obsObj = observable({
    title: 'hello world',

    get extendTitle() {
        return `${this.title} mobx`
    }
})
 autorun(() => {
    console.log('mobx computed title:', obsObj.extendTitle)
})

const fn = action(function(){
    obsObj.title = 'title change'
})
fn()
Copy the code

The output is:

otuput:
mobx computed title:' hello world mobx
mobx observal title: title change mobx
Copy the code

Compared with the previous example, there is a computed property, namely extendTitle, which will also become observable. You can see that extendTitle depends on title, so when title changes, computed automatically generates new values. The extendTitle that Autorun depends on has changed, so it is executed automatically again. (It is worth noting that recalculation logic is performed only when the property is not evaluated). There is also an action that wraps the method that will change the data with an action. This is not required, but it is necessary in large and complex applications because the change in state must occur in the action, making it easier to locate the problem. So mobx has configuration parameters that can be set to change observable data that must be wrapped in action.

So far, the mobx execution flow and important concepts have been clearly understood through the above two demos.

Mobx API

Mobx API is also relatively simple and easy to understand, which can be divided into three categories. The APIS used in the demo above have their own categories. This part will briefly talk about these three categories of apis, of course, is the essence of self-understanding, specific and complete that is the official website, and it can not be finished in one article.

1. Observables class API

Mobx can turn JS primitive data types, reference types, ordinary objects, class instances, arrays, maps, and sets into an observable.

* observable

This is a handy API, Observable (value), that converts to Array, Map, and Set only when value is object. Errors are reported for primitive data types, non-ordinary objects, and functions. Note: An ordinary Object is an Object whose prototype is Object, or an Object with no prototype, created using an Object literal created in curly braces or object.create (null)

* observable.box

It can be any data, and is generally used for basic data types, Settings and retrieves, and becomes observable in a different way than an Observable. For example, a demo on the official website:

import {observable} from "mobx";

const cityName = observable.box("Vienna");

console.log(cityName.get());

cityName.observe(function(change) {
    console.log(change.oldValue, "- >", change.newValue);
});

cityName.set("Amsterdam");
Copy the code
* extendObservable

ExtendObservable is used to make observable objects generated with constructors and objects that are not null in the Object.create stereotype.

var Person = function(firstName, lastName) {// Initialize observable property extendObservable(this, {firstName: firstName, lastName:) on a new instance lastName, getfullName() {
            return this.firstName + "" + this.lastName
        },
        setFirstName(firstName) {
            this.firstName = firstName
        }
    }, {
        setFirstName: action
    });
}
var matthew = new Person("Matthew"."Henry");
extendObservable(matthew, {
    age: 353
});
Copy the code

These apis basically do most of what our applications want, making data observable.

2. Reactions class API

These reactions refer to reacting to observable data, which can be either a new value or a side effect such as printing a log, updating the logic of a view, etc.

* computed

A very well understood API is the computed property, which generates a new value based on the dependent mutable data, and this new value is also observable. Mobx is well optimized for performance. The value of a calculated property that is not used during a state change is not recalculated and is garbage collected if it is no longer referenced.

* autorun

This is the response function, depending on the state change, automatic execution of the function, so easy.

* the when and reaction

These two can be completely seen as autorun syntax sugar, is an enhancement of Autorun functionality. Look at the API on the website and it’s very easy to understand.

Note: We need to figure out what the derivative will respond to. MobX will respond to reading existing observable properties during the execution of the trace function. When an observable property is read in a derivative, it responds to subsequent state changes.

3. API of action class

Action is an action that triggers the change of observable state and forms a closed loop. As can be seen from the above two demos, action wrapping is not necessary, but it is necessary for large-scale applications to force action wrapping for some data changing operations. This is very useful for system maintenance and troubleshooting.

* action

If you want to force action to be wrapped, you need to configure mobx config globally:

const { configure} from "mobx"

configure({
    enforceActions: 'always'
});
Copy the code
* runInAction tool functions

If an action wrapped function has an asynchronous callback (promise’s then, setTimeout callback), and if it changes state, it also needs to have an action wrapped, runInAction, which is also the syntactic sugar of the action, Place the final state change in the asynchronous callback in a function, wrapped in the runInAction.

* flows

Write the async as a generator and then wrap it with FLOWS.

A decorator API

Those three apis are what Mobx has in mind, but mobx is really handy with posture decorator mode. The following two demos using decorators include the use of the above three apis:

demo1:
import { observable, computed, autorun } from "mobx";
class OrderLine {
    @observable price = 0;
    @observable amount = 1;

    @computed get total() {
        return this.price * this.amount;
    }
}

const obj = new OrderLine()

autorun(() => {
    console.log(obj.amount)
})

obj.amount = 2
Copy the code

The above is a coding that supports decorator writing under the transformation of Babel or TS. If not, decator API is provided as follows:

demo2: 
import { observable, computed, action, decorate } from "mobx"
class OrderLine {
    price = 0;
    amount = 1;
    get total() {
        return this.price * this.amount;
    }
    setPrice() {
        this.price = 2
    }
}
decorate(OrderLine, {
    price: observable,
    amount: observable,
    total: computed,
    setPrice: action,
})

Copy the code

Mobx debugging

Mobx has a built-in Trace API that helps us debug during development. By adding trace(true) to computed, Autorun and other response functions in a derived (computed, Autorun and other response functions), you can perform debugger in response to state changes, and through debugging information you can see which state changes trigger its response, which states the derived depends on, and the code that locates the change.

Demo: 
import  {observable, autorun, trace} from 'mobx'
const obsObj = observable({
    title: 'hello world',
    name: 'trace demo'
})

 autorun((r) => {
    trace(true)
    console.log('name: ', obsObj.name)
})
obsObj.name = 'title changed'
Copy the code

In the demo above, autorun is automatically executed when obsobj.name changes, and you can see the following breakpoint information in Chrome:

Mobx combined with the MVVM framework

Mobx doesn’t rely on the view-layer framework. It works with React, VUE, Angular, and only needs a connector, but it’s used with React the most. The principle of friendmobx is not difficult to understand, just use render as a derivative of the view, all the states in render become observable, then render again, update the view. As shown below:

portal

conclusion

The above are some main ideas and APIS of MOBx. Through this article, you can spend less time to understand mobx. If you need to go deeper, you can carefully read mobx’s official website, as well as the comparison of MOBx and Redux, you can also search a lot of articles.