How Mobx works

mobx works

推荐版本: "mobx-react": "4.1.0", "mobx": "^2.7.0 || ^3.0.0"

1 Mobx Points

1.1 and allowed to define the state can be observed

It may be any data structure to store state, such as the object, an array type, marked with the marking mobx becomes observable.

import { observable } from 'mobx';
var appStore = observable({
    timer: 0;
});

1.2 Create a view state change response

mobx with minimal update the view, any function can be responsive view observation data itself. 

import {observer} from 'mobx-react';
@observer
class TimerView extends React.Component {
    render() {
        return (
            <button onClick={this.onReset.bind(this)}>
                Seconds passed: {this.props.appState.timer}
            </button>
        );
    }
    onReset() {
        this.props.appState.resetTimer();
    }
};
ReactDOM.render(<TimerView appState={appState} />, document.body);

1.3 Change Status

mobx changes state with a simple and intuitive way, using the action (action can be configured to enforce Mobx Update) or directly modified

2 concepts and principles

2.1 State status

Status is data driven applications. The state of affairs as a specific to-do list, as well as the currently selected element in view state. 
There are states like Excel spreadsheet data.

2.2 derivations derivative

What is derived, from the state of things and there will be no further interaction is derived. 

  • User Interface 
  • Derived data, and the rest do list 
  • Back-end integration, such a change transmits it to the server 
    mobx integrates two types of derivative

Computed values ​​calculated attribute value

Use pure function may be derived from the current observation state value. 

Reactions reaction

It is a side effect occurs automatically when the need to change the State. . The need for a bridge linking functional programming and reactive programming 
initial use mobx will often use reactions, it is recommended to use computed, the concept back to the table, the formula is derived from the calculated value. 

Actions action

Any period of operation status code may be changed. A user operation, push the rear end of the data, predetermined events. 
Operation similar to enter a new value in the table cell. mobx custom action can be displayed, @ action. 

Principle 3

mobx supports unidirectional data flow, an operation to change the state to change the state of State updates the affected view. 
action ---> state ---> view 
when the State is changed, all derived atomic level are automatically updated intermediate value therefore not possible to observe 
all of the default derived are thus after synchronization update operation can be safely check Calcd 
Calcd delay is updated. Any calculated value is not in use are not updated until they are needed will be side effects (IO), garbage collection automatically when not in use 
calculated values should not be to change the state, should be a pure side effects. 

4 core API

主要api: Computed 、 observable 、 reactions 、 actions  

4.1 observable

observable(value);
@observable property = value;

Observable observed value may be substantially types, reference types, normal object class instance, and mapping array. 
The main types of conversion rules, or trimming (modified class, function) by decorators

  • If the observed value is ES6 instance, it will return a new Observe Map, ES6 based. If you do not modify only one entry in the change 
    but, react when you add or delete other entry, Observe Map is useful. 
  • If the observed value is an array, it will return a Observe Array 
  • If the value is what object prototypes (objects can destroy prototypes) or prototype Object.prototype, the object is cloned and all attributes are converted into observable Observe Object 
  • If there is a prototype value, such as functions, the array may have four processing method Boxed Observer
    • Display call observable.box (value) a little magic
    • @observable common
    • Calls decorate ()
    • Introducing class extendObservable () can be used to introduce the decorative default attribute is infected, observalbe are automatically applied to the data structure contains any value,
      Observable is extendObservable (this, {prototype: value }) syntactic sugar observable.object (obj , decorator, option) the default values are converted into observation 
      observable.array (obj, option) generates an array of observable, if not each value is observed, may be provided Deep {:} to false 
      observable.map (obj, Option ) need not be limited string

4.2 decorator Decorator

The list of these is available decoration:

  • observable.deep default observable decorator 
  • computed create a derivative, which is able to automatically obtain a function of the modified value and returns the new value 
  • action to create action 
  • action.bound have created a range of actions 
class TodoList {
    todos = {}
    get unfinishedTodoCount() {
        return values(this.todos).filter(todo => !todo.finished).length
    }
    addTodo() {
        const t = new Todo()
        t.title = 'Test_' + Math.random()
        set(this.todos, t.id, t)
    }
}
decorate(TodoList, {
    todos: observable,
    unfinishedTodoCount: computed,
    addTodo: action.bound
})   // 对类 Observable 转换 

4.3 calculate property Computed

Usage several, it seems only a few minor differences:

  • computed( () => expression) 
  • computed( () => expression, (newvalue) => void ) 
  • computed( () => expression, option ) 
    @computed({ equals: compareFn }) get property() { return expression; } 
    @computed get classProperty() { return expression; } 

Computed comes with a lot of operational attributes control the behavior of Computed 

  • Comparator algorithms equals: (value, value) => boolean detection rules to override the default comparison function. Built-in comparator has: comparer.identity, comparer.default, comparer.structural 
  • Other types of observable tracking property value, waiting to return after doing the calculation requiresReaction: boolean before re-calculation derived property, waiting for tracking observables value changes

- GET: () => value 
- SET: (value) => void 
- the keepAlive: Calcd Boolean holding activities, not only after the value change. 

4.4 Action Actions

Anything to modify the status of 
recommendations Actions modifications at any function or changes observable side effects of 

4.5 Flow stream processing

flow (function * (args) {}) 
flow () as a function of his generator receives only input 
key role is to ensure that the code flow is packaged action processing asynchronous code, because the normal operation is not observable state by asynchronous enforceActions inspection. 
Magic flow can not solve the problem of asynchronous tracking 
note must be asynchronous function generator, but also in the interior can only yield promises 

import { configure, flow } from 'mobx';

// 不允许在动作外部修改状态 严格模式的意思
configure({ enforceActions: true });

class Store {
    @observable githubProjects = [];
    @observable state = "pending"; // "pending" / "done" / "error"


    fetchProjects = flow(function* fetchProjects() { // <- 注意*号,这是生成器函数!
        this.githubProjects = [];
        this.state = "pending";
        try {
            const projects = yield someAsyncProcess(); // 用 yield 代替 await
            const filteredProjects = somePreprocessing(projects);

            // 异步代码自动会被 `action` 包装
            this.state = "done";
            this.githubProjects = filteredProjects;
        } catch (error) {
            this.state = "error";
        }
    })
}

Flows may revoke, cancel promise of the call () method stops the asynchronous state value, will continue finally clause.

5 observables respond

5.1 computed

Calcd is derived based on the existing state or other calculated values. 
Conceptually, the values in the table and they are very similar, such as a summary of more than 80 students. 
Attribute value of the actual calculation can be made as small as possible may be modified to calculate the attribute is highly optimized, multi-can 

5.2 computed & autorun

Create a calculated attribute type declaration may be used in the decorative properties of arbitrarily

import { observable, computed } from 'mobx';

class orderline {
    @observable price = 10;
    @observable amount = 1;

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

    
}

Mobx 学习
基本写法
* 此处声明式的监控变量,与 ES6 的类修饰不同。

import { observable, action, computed, toJS } from 'mobx' import { observer } from 'mobx-react'

export default class InstanceStore { @observable value = 1

@action
modifyValue(v) {
    this.value = v
}
@computed get getValue() {
    return this.value * 10;
}

}

direct access to the computed value of a calculation.

If a value is a need to calculate the state, and also needs to be observed can be used similar @computed autorun

autorun to perform some action and values ​​related changes, such as asynchronous requests, data processing

computed according to the existing value, we calculate a new value returns a value of the tracking result of the observation var ins = new InstanceStore (); console.log ( 'value form mobx computed', toJS (ins.getValue ()))

autorun in case of need to continue to use for garbage collection

var numbers = observable([1,2,3]);

var sum = computed(() => numbers.reduce((a, b) => a + b, 0));

var disposer = autorun(() => console.log(sum.get())); // '6'

numbers.push(4);                                                  // '10'

dispose () ;

numbers.push (5); // What is not printing, because disposer execution is no longer on the autorun reaction

Expired state value as follows

var ins = new InstanceStore();

console.log(toJS(ins.value),'get value from mobx');

dispatch modified value of var ins = new InstanceStore (); ins.modifyValue (1000);

@Observer class may be used in the observer model component routeCreate extends Component {constructor (props) {super (props); this.store = new InstanceStore ();} ...}

Use observer modifying components, and there are references mobx values, will be one more component life cycle componentWillReact // redux change the value of the way is to generate a new object by copying the original object, componentWillReceiveProps trigger assembly // mobx is inside render the original generate a new object on the basis of values, the same reference before it mobx not trigger ReceiveProps cycle


异步处理
mobx 状态值为同步更新。

export default class InstanceStore { @observable value = 1

@action
modifyValue(v) {
    this.value = v;
    setTimeout(this.valueAdd, 100);
}
@action.bound
valueAdd(v) {
    this.value = v + 20;
}

}

// .bound 是js执行环境语法糖
// 过多action ? 需要简化写法
// mobx 自身提供了一个工具函数帮助跟新对应action中的值 runInAction

export default class InstanceStore {

   @observable value = 1

@action
asyncModifyValue(v) {
    this.value = v;
    setTimeout(action('valueAdd', () => {
        this.value = v + 20
    }), 100);
}

@action
asyncModify(v) {
    this.value = v;
    setTimeout(runInAction(() => {
        this.value = v + 20
    }), 100);
}

}

//  异步action,action可以这样写
@asyncAction
changeValue() {
    this.value = 0;
    const data = yield Promise.resolve(1)
    this.value = data;
}


toJS 将mobx state 序列转换为js可识别类型?

更新action的约束
mobx 非强制使用action改变state;如果要加强制action触发state可以通过 
Mobx.configure({enforceActions: true}) 加限制条件,强制通过action更新,适用于大型项目



以下是遗留问题
* 1, mobx 是否是同步更新 是
* 2, mobx toJS是如何实现的  
* 3,store对应单个变量,会按照类型预留数组空间,是什么原因
* 4,使用toJS获取数据,需要在class名称上面加 @observer 吗
* 5,为什么mobx取值,是如此的简介?,而且是支持多状态
* 6,extendObservable 可以按照扩展的方式 装饰函数或class里的对象

Guess you like

Origin www.cnblogs.com/the-last/p/11221076.html