状态管理库 MobX 和 react

MobX

  • MobX 是一个简单、方便扩展、久经考验的状态管理解决方案

基本概念

  • MobX 是一个独立的组件,能够配合各类框架使用,因为项目中须要使用 react & MobX。下面来详细了解一下javascript

  • State 是每个应用程序的核心部分,而使用一个不合规范的 State 则是让你的应用充满 bug 和失控的不二法门,或者就是局部变量环绕,让你的 state 失去了同步。有不少框架试图解决这个问题,好比使用不可变的 state,可是这样以来又带来了新的问题,好比数据必须规格化,完整性约束失效等等。java

MobX 功能

  • MobX 让整个事情又变简单了:它不容许产生失控的 state。它的理念也很简单:全部能够从 state 中派生的事物,都会自动的派生。react

  • demo程序员

class TodoStore {
	todos = [];

	get completedTodosCount() {
    	return this.todos.filter(
			todo => todo.completed === true
		).length;
    }

	report() {
		if (this.todos.length === 0)
			return "<none>";
		return `Next todo: "${this.todos[0].task}". ` + 
			`Progress: ${this.completedTodosCount}/${this.todos.length}`; 
	}

    addTodo(task) {
		this.todos.push({ 
			task: task,
			completed: false,
            assignee: null
		});
	}
}

const todoStore = new TodoStore();
复制代码

当咱们去建立一个 todoStore,他拥有一个 todos 集合,如今咱们往这个 todoStore 里添加一些东西,为了明显起见,就调用 todoStore.report数组

todoStore.addTodo("read MobX tutorial");
console.log(todoStore.report());
​
todoStore.addTodo("try MobX");
console.log(todoStore.report());
​
todoStore.todos[0].completed = true;
console.log(todoStore.report());
​
todoStore.todos[1].task = "try MobX in own project";
console.log(todoStore.report());
​
todoStore.todos[0].task = "grok MobX tutorial";
console.log(todoStore.report());

复制代码
  • 太巧了,这就是 MobX 能为你作的事情。自动执行只在 state 改变的时候触发,就好像 Excel 中的图表只在单元格数据改变时更新同样。为了达到这个目标,TodoStore 必须成为可观测的(observable)才行,让咱们来改一些代码。

observable & computed

同时,completedTodosCount 属性应该被自动派生,使用 @observable 和 @computed 装饰器来作这些事情:架构

class ObservableTodoStore {
    @observable todos = [];
    @observable pendingRequests = 0;
 
    constructor() {
        mobx.autorun(() => console.log(this.report));
    }
 
    @computed get completedTodosCount() {
    	return this.todos.filter(
			todo => todo.completed === true
		).length;
    }
 
    @computed get report() {
        if (this.todos.length === 0)
            return "<none>";
	return `Next todo: "${this.todos[0].task}". ` + 
	    `Progress: ${this.completedTodosCount}/${this.todos.length}`; 
	}
 
    addTodo(task) {
	this.todos.push({ 
	    task: task,
	    completed: false,
	    assignee: null
	});
    }
}
 
const observableTodoStore = new ObservableTodoStore();

复制代码
  • 在这个构造器中,咱们使用 autorun 包裹了一个打出 report 的小函数。Autorun 里的东西首先会运行一次,而后当其中的函数有 observable 的数据发生变化时,会再次运行。 这里咱们使用了 todos 属性,每次 todos 变化了咱们就打印出新的东西。
  • 测试一下
observableTodoStore.addTodo("read MobX tutorial");
observableTodoStore.addTodo("try MobX");
observableTodoStore.todos[0].completed = true;
observableTodoStore.todos[1].task = "try MobX in own project";
observableTodoStore.todos[0].task = "grok MobX tutorial";

复制代码

举个栗子(sf 的一个问题有感)

  • 对于单个对象,我可使用computed经过计算得到一些属性,好比
@observable good = {
    number: 2,
    price: 3
}
@computed get totalPrice() {
    return this.good.number * this.good.price;
}

// 数组
@observable goodsList = [{
    number: 2,
    price: 3
},{
    number: 2,
    price: 3
}]
复制代码
  • 问题?框架

    • 这种状况我如何经过computed得到数组某个元素的计算属性呢,仍是只能在改变number的函数中手动去更改,可是我数组的对象中并无一个totalPrice的属性,每次把单个good push到goodsList中去还要给good添加一个totalPrice属性岂不是很麻烦
  • 解决方案函数

    • good 弄成一个单独的model文件
export default class Good{
  @observable number;
  @observable price;
  constructor(number, price) {
    this.number = number;
    this.price = price;
  }
  
  @computed
  get totalPrice() {
    return this.number * this.price
  }   

}
复制代码
    • 而后在goodList文件中
    • 这样就实现了自动计算, 访问的时候相似 this.props.goodList[0].totalPrice
@action
  addGood(...args) {
    this.todos.push(new Good(...args));
  }
复制代码
  • 未完待续...

总结

  • 最后总结一些:
  • @observale 修饰器或者 observable 函数让对象能够被追踪;
  • @computed 修饰器创造了自动运算的表达式;
  • autorun 函数让依靠 observable 的函数自动执行,这个用来写 log,发请求很不错;
  • @observer 修饰器让 React 组建自动起来,它会自动更新,即使是在一个很大的程序里也会工做的很好;
  • MobX 不是一个状态容器

不少人把 MobX 看成另一个 Redux,可是它仅仅是一个库,不是一个什么架构。上面的例子仍是须要程序员本身去组织逻辑和 store 或者控制器什么的.测试

引用:

10分钟极速入门 MobX ui

sf @computed使用

react 官网

相关文章
相关标签/搜索