mobx(简单、可扩展的状态管理)

862

核心概念

Observavle(创建观察对象)

MobX 为现有的数据结构(如对象,数组和类实例)添加了可观察的功能。 通过使用 @observable 装饰器(ES.Next)来给你的类属性添加注解就可以简单地完成这一切。 它无法使原始数据类型值转变成可观察.

import { observable } from "mobx";

const list = observable([1, 2, 4]);
// 或者
class Todo {
    id = Math.random();
    @observable title = "";
    @computed get name() {
        return this.title
    }
}
//observable.array(values?)
可以将数组转变为可观察的。 这也是递归的

// observable.box(value, { deep: false })
const cityName = observable.box("Vienna");
console.log(cityName.get());
cityName.set("Amsterdam");
console.log(cityName.get());
// 输出 'Vienna'
// 输出 'Amsterdam'

@observable 装饰器是extendObservable(this, { property: value }) 的语法糖。

(@)computed 不要把 computed 和 autorun 搞混。它们都是响应式调用的表达式,但是,如果你想响应式的产生一个可以被其它 observer 使用的值,请使用 @computed

(@)autorun 当你想创建一个响应式函数,而该函数本身永远不会有观察者时,可以使用 mobx.autorun。经验法则:如果你有一个函数应该自动运行,但不会产生一个新的值,请使用autorun。

var numbers = observable([1,2,3]);
var sum = computed(() => numbers.reduce((a, b) => a + b, 0));
// autorun 对它函数中使用的任何东西作出反应
var disposer = autorun(() => console.log(sum.get()));
// 输出 '6'
numbers.push(4);
// 输出 '10'
disposer(); 
// 传递给 autorun 的函数在调用后将接收一个参数,即当前 reaction(autorun),可用于在执行期间清理 autorun。
numbers.push(5);
// 不会再输出任何值。`sum` 不会再重新计算。

reaction autorun 的变种,对于如何追踪 observable 赋予了更细粒度的控制。就类似于autorun里面有两个观察值变化,我只想其中一个变化才触发更新,那就用reaction

reaction(() => data, (data, reaction) => { sideEffect }, options?)。

第一个参数用来追踪并返回数据作为第二个函数(效果 函数)的输入
第二个函数(副作用函数)当调用时会接收两个参数。 第一个参数是由 data 函数返回的值。 第二个参数是当前的 reaction,可以用来在执行期间清理 reaction.dispose();

粗略地讲,reaction 是 computed(expression).observe(action(sideEffect)) 或 autorun(() => action(sideEffect)(expression)) 的语法糖。 @observer 当观察值变量,要想组件相应变化,只需要用observer函数,装饰器包起来

@observer function Main {}
//
const Main = observer(() => {})

action 动作是任何用来修改状态的东西,action可以帮助我们修改状态值。

class Ticker {
    @observable tick = 0

    @action.bound
    increment() {
        this.tick++ // 'this' 永远都是正确的
    }
}
const ticker = new Ticker()
setInterval(ticker.increment, 1000)

注意: action.bound 不要和箭头函数一起使用;箭头函数已经是绑定过的并且不能重新绑定。

runInAction 是个简单的工具函数,它接收代码块并在(异步的)动作中执行

  @action
  fetchCurrentUser = () => {
    fetchCurrentUser().then(
      ({ data }) => {
        runInAction(() => {
          this.currentUser = data;
        });
      },
      () => {
        history.push('/login');
      },
    );
  };